| composition | {"steps":[{"id":"collect","kind":"user_input","with":{"prompt":"Paste the community research transcript or notes, plus any project\ncontext and target audience. Include only source material you want the\ninsight brief to analyze.\n"},"clarify":{"mode":"chat","extract_natural_language":true,"cancel_words":["cancel","取消","stop","abort"],"timeout_seconds":1800}},{"id":"analyze","kind":"llm_chat","depends_on":["collect"],"on_failure":"analyze_fallback","output_contract":{"format":"json","required_properties":["key_pain_points","stakeholder_needs","opportunities"]},"with":{"system_prompt":"You are a community research analyst. Extract grounded themes from\nthe provided transcript or notes. Do not invent quotes or attribute\nviews to named people unless the source explicitly does. Return ONLY\none JSON object and do not use markdown fences.\n","input":"Analyze the following community research material and return ONLY a\nsingle JSON object.\n\nTranscript or notes:\n{{ outputs.collect | truncate(50000) }}\n\nReturn this JSON structure:\n{\n \"key_pain_points\": [\"...\"],\n \"stakeholder_needs\": [\"...\"],\n \"opportunities\": [\"...\"],\n \"evidence_summary\": \"...\",\n \"gaps\": [\"...\"]\n}\n\nRules:\n- Every pain point must be grounded in the source.\n- Separate evidence from inference.\n- Flag missing context under the \"gaps\" key.\n- Do not invent quotes, names, dates, or statistics.\n- Do not recommend replacing community engagement with automation.\n"}},{"id":"analyze_fallback","kind":"llm_chat","output_contract":{"format":"json","required_properties":["key_pain_points","stakeholder_needs","opportunities"]},"with":{"system_prompt":"You are a community research analyst on a fallback path. Produce a\ngrounded, best-effort JSON analysis from the available source material.\nReturn ONLY one JSON object. Do not use markdown fences.\n","input":"Analyze the following research material and return structured JSON:\n\n{{ outputs.collect | truncate(30000) }}\n\nReturn this JSON structure:\n{\n \"key_pain_points\": [\"...\"],\n \"stakeholder_needs\": [\"...\"],\n \"opportunities\": [\"...\"],\n \"evidence_summary\": \"...\",\n \"gaps\": [\"...\"]\n}\n"}},{"id":"draft","kind":"llm_chat","depends_on":["analyze"],"output_contract":{"format":"json","required_properties":["executive_summary","key_pain_points","stakeholder_needs","opportunity_map","risks_and_cautions","follow_up_questions"]},"with":{"system_prompt":"You are drafting a community research insight brief for human review.\nReturn ONLY a single JSON object. Do NOT wrap it in ```json fences.\nDo NOT include ANY text before or after the JSON. Your entire response\nmust be parseable as a JSON object starting with { and ending with }.\nEvery key claim must be grounded in the analysis results provided.\nDo not invent quotes, names, dates, or statistics not present in the\nsource.\n","input":"Draft a complete insight brief from the analysis below.\nOutput ONLY the JSON — no markdown, no explanation, no code fences.\n\nAnalysis results:\n{{ outputs.analyze | truncate(8000) }}\n\nProject context:\n{{ outputs.collect | truncate(2000) }}\n\nReturn this exact JSON structure (no markdown fences):\n{\n \"executive_summary\": \"<2-4 sentences>\",\n \"key_pain_points\": [\n {\"issue\": \"...\", \"evidence\": \"...\", \"severity\": \"high|medium|low\"}\n ],\n \"stakeholder_needs\": [\n {\"group\": \"...\", \"need\": \"...\", \"urgency\": \"high|medium|low\"}\n ],\n \"opportunity_map\": [\n {\"opportunity\": \"...\", \"feasibility\": \"high|medium|low\", \"impact\": \"high|medium|low\"}\n ],\n \"risks_and_cautions\": [\n {\"risk\": \"...\", \"likelihood\": \"high|medium|low\", \"mitigation\": \"...\"}\n ],\n \"follow_up_questions\": [\"...\"],\n \"missing_information\": [\"...\"],\n \"attribution_note\": \"<explicit statement about what is evidence vs inference>\"\n}\n"}},{"id":"validate","kind":"llm_chat","depends_on":["draft"],"output_choices":["PASS","REVISE"],"route":[{"when":"{{ outputs.validate == 'PASS' }}","to":"preview"},{"to":"validation_revise"}],"with":{"system_prompt":"You are a strict grounding validator. Return exactly PASS or REVISE.\n","input":"Classify whether this draft brief is ready for human preview.\nReturn PASS only if every checklist item is satisfied. Return REVISE\nif any claim lacks grounding, overstates automation, omits risks, or\ninvents quotes, names, dates, or statistics.\n\nDraft brief:\n{{ outputs.draft | truncate(8000) }}\n\nOriginal analysis:\n{{ outputs.analyze | truncate(5000) }}\n\nValidation checklist:\n- Every key claim is grounded in the transcript or provided context.\n- Recommendations are framed as support tools, not replacements for relationships.\n- Missing information is listed separately.\n- Risks are included alongside opportunities.\n- No invented quotes, names, dates, or statistics.\n"}},{"id":"validation_revise","kind":"llm_chat","depends_on":["validate"],"with":{"system_prompt":"You are a grounding validator. The draft brief did not pass validation.\nExplain the revision requirement clearly and do not publish the brief.\n","input":"The draft research insight brief needs revision before preview.\n\nDraft brief:\n{{ outputs.draft | truncate(8000) }}\n\nOriginal analysis:\n{{ outputs.analyze | truncate(5000) }}\n\nReturn a concise Markdown message explaining that the brief is blocked\npending revision and list the likely grounding, risk, or attribution\nissues to address.\n"}},{"id":"preview","kind":"llm_chat","depends_on":["draft","validate"],"with":{"system_prompt":"You are preparing a research insight brief for human review.\nPresent the validated findings in a clean Markdown format.\n","input":"Produce a human-readable preview of the validated insight brief.\n\nValidated draft:\n{{ outputs.draft | truncate(8000) }}\n\nValidation result:\n{{ outputs.validate | truncate(2000) }}\n\nInclude:\n1. Executive Summary\n2. Key Pain Points (with severity)\n3. Stakeholder Needs (with urgency)\n4. Opportunity Map (with feasibility and impact)\n5. Risks and Cautions (with mitigations)\n6. Follow-up Questions\n7. Missing Information\n8. Attribution Note\n\nEnd with:\n---\n**Status**: Awaiting human review.\nReply \"approve\", \"revise\", or \"reject\" to proceed.\n"}},{"id":"review","kind":"user_input","depends_on":["preview"],"with":{"prompt":"{{ outputs.preview | truncate(12000) }}\n"},"clarify":{"mode":"chat","extract_natural_language":true,"cancel_words":["reject","拒绝","abort"],"timeout_seconds":86400}},{"id":"final_response","kind":"llm_chat","depends_on":["preview","review"],"with":{"system_prompt":"You are finalizing a community research insight brief after human\nreview. Respect the reviewer decision exactly.\n","input":"Review decision and feedback:\n{{ outputs.review | truncate(2000) }}\n\n{% if 'approve' in outputs.review %}\nProduce the final approved brief from the preview below.\nMark it as APPROVED and ready for distribution.\n\n{{ outputs.preview | truncate(8000) }}\n\n{% elif 'revise' in outputs.review %}\nRevision requested. Feedback:\n{{ outputs.review | truncate(2000) }}\n\nRe-analyze the source material incorporating this feedback and produce\na revised Markdown brief. Keep all claims grounded in the transcript.\n\nOriginal transcript:\n{{ outputs.collect | truncate(50000) }}\n\n{% else %}\nBrief rejected. No further action.\nReason from reviewer:\n{{ outputs.review | truncate(1000) }}\n{% endif %}\n"}}]} |