docs(06): create phase plans for consensus & export
Phase 06: Consensus & Export - 2 plans created - 4 total tasks defined - Ready for execution Plan 06-01: Consensus generation (M6) Plan 06-02: Markdown export (M7) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
bd1db003b7
commit
ddb0de0757
2 changed files with 286 additions and 0 deletions
129
.planning/phases/06-consensus-export/06-01-PLAN.md
Normal file
129
.planning/phases/06-consensus-export/06-01-PLAN.md
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
---
|
||||||
|
phase: 06-consensus-export
|
||||||
|
plan: 01
|
||||||
|
type: execute
|
||||||
|
---
|
||||||
|
|
||||||
|
<objective>
|
||||||
|
Implement consensus generation for multi-model discussions.
|
||||||
|
|
||||||
|
Purpose: Enable users to synthesize discussion outcomes into structured agreements/disagreements (M6 milestone).
|
||||||
|
Output: Working /consensus command that generates and displays AI-summarized consensus.
|
||||||
|
</objective>
|
||||||
|
|
||||||
|
<execution_context>
|
||||||
|
~/.claude/get-shit-done/workflows/execute-phase.md
|
||||||
|
~/.claude/get-shit-done/templates/summary.md
|
||||||
|
</execution_context>
|
||||||
|
|
||||||
|
<context>
|
||||||
|
@.planning/PROJECT.md
|
||||||
|
@.planning/ROADMAP.md
|
||||||
|
@.planning/STATE.md
|
||||||
|
|
||||||
|
# Prior phase context (discussion infrastructure):
|
||||||
|
@.planning/phases/05-multi-model-discussions/05-03-SUMMARY.md
|
||||||
|
|
||||||
|
# Source files to modify/reference:
|
||||||
|
@src/moai/core/models.py
|
||||||
|
@src/moai/core/orchestrator.py
|
||||||
|
@src/moai/core/services/discussion.py
|
||||||
|
@src/moai/bot/handlers/discussion.py
|
||||||
|
@src/moai/bot/handlers/commands.py
|
||||||
|
|
||||||
|
**Tech stack available:** python-telegram-bot, sqlalchemy, openai SDK, asyncio
|
||||||
|
**Established patterns:** Service layer in core/services/, orchestrator for AI calls, handler delegation to services
|
||||||
|
|
||||||
|
**Constraining decisions:**
|
||||||
|
- Phase 05-03: build_context() assembles discussion history for AI context
|
||||||
|
- Phase 05-01: Discussion service with eager loading via selectinload
|
||||||
|
- Phase 04-01: AI client singleton pattern, MODEL_MAP for short names
|
||||||
|
|
||||||
|
**SPEC.md consensus format:**
|
||||||
|
- agreements: string[] (bullet points)
|
||||||
|
- disagreements: [{topic, positions: {model: position}}]
|
||||||
|
- Consensus model already exists with these fields
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<tasks>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 1: Add consensus generation to orchestrator and service</name>
|
||||||
|
<files>src/moai/core/orchestrator.py, src/moai/core/services/discussion.py</files>
|
||||||
|
<action>
|
||||||
|
1. In orchestrator.py, add CONSENSUS_PROMPT constant with instructions to analyze discussion and return JSON with "agreements" (list of strings) and "disagreements" (list of {topic, positions} objects).
|
||||||
|
|
||||||
|
2. Add `generate_consensus(discussion: Discussion, model: str = "claude") -> dict` function:
|
||||||
|
- Build context from discussion using existing build_context()
|
||||||
|
- Append CONSENSUS_PROMPT as final user message
|
||||||
|
- Call AI client with system prompt explaining the task
|
||||||
|
- Parse JSON response (handle parsing errors gracefully)
|
||||||
|
- Return dict with "agreements" and "disagreements" keys
|
||||||
|
|
||||||
|
3. In discussion.py service, add:
|
||||||
|
- `save_consensus(discussion_id: str, agreements: list, disagreements: list, generated_by: str) -> Consensus`
|
||||||
|
- `get_consensus(discussion_id: str) -> Consensus | None`
|
||||||
|
|
||||||
|
Use existing session patterns (async with get_session()). Import Consensus model.
|
||||||
|
</action>
|
||||||
|
<verify>Python imports succeed: `python -c "from moai.core.orchestrator import generate_consensus; from moai.core.services.discussion import save_consensus, get_consensus"`</verify>
|
||||||
|
<done>generate_consensus() returns dict with agreements/disagreements, save_consensus() persists to DB, get_consensus() retrieves</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 2: Create /consensus command handler</name>
|
||||||
|
<files>src/moai/bot/handlers/discussion.py, src/moai/bot/handlers/commands.py, src/moai/bot/handlers/__init__.py</files>
|
||||||
|
<action>
|
||||||
|
1. In discussion.py handlers, add `consensus_command(update, context)`:
|
||||||
|
- Get selected project (error if none)
|
||||||
|
- Get active discussion for project (error if none, suggest /open or /discuss first)
|
||||||
|
- Check if consensus already exists (get_consensus) - if so, display existing
|
||||||
|
- Otherwise call generate_consensus() with discussion
|
||||||
|
- Save consensus via save_consensus()
|
||||||
|
- Format and display:
|
||||||
|
```
|
||||||
|
**Consensus Summary**
|
||||||
|
|
||||||
|
**Agreements:**
|
||||||
|
- point 1
|
||||||
|
- point 2
|
||||||
|
|
||||||
|
**Disagreements:**
|
||||||
|
- **Topic:** {topic}
|
||||||
|
- Claude: {position}
|
||||||
|
- GPT: {position}
|
||||||
|
|
||||||
|
_Generated by {model}_
|
||||||
|
```
|
||||||
|
- Show typing indicator while generating
|
||||||
|
|
||||||
|
2. Register handler in __init__.py: `CommandHandler("consensus", consensus_command)`
|
||||||
|
|
||||||
|
3. Update HELP_TEXT in commands.py to add consensus under Output section:
|
||||||
|
`/consensus` - Generate consensus summary
|
||||||
|
</action>
|
||||||
|
<verify>Bot responds to /consensus with either consensus output or appropriate error message</verify>
|
||||||
|
<done>/consensus generates and displays consensus for active discussion, or shows existing if already generated</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
</tasks>
|
||||||
|
|
||||||
|
<verification>
|
||||||
|
Before declaring plan complete:
|
||||||
|
- [ ] `ruff check src/moai/core/orchestrator.py src/moai/core/services/discussion.py src/moai/bot/handlers/`
|
||||||
|
- [ ] `python -c "from moai.core.orchestrator import generate_consensus"` succeeds
|
||||||
|
- [ ] `python -c "from moai.core.services.discussion import save_consensus, get_consensus"` succeeds
|
||||||
|
</verification>
|
||||||
|
|
||||||
|
<success_criteria>
|
||||||
|
|
||||||
|
- generate_consensus() calls AI and returns structured dict
|
||||||
|
- Consensus persisted to database via save_consensus()
|
||||||
|
- /consensus command displays formatted consensus
|
||||||
|
- Help text updated
|
||||||
|
- No ruff errors
|
||||||
|
</success_criteria>
|
||||||
|
|
||||||
|
<output>
|
||||||
|
After completion, create `.planning/phases/06-consensus-export/06-01-SUMMARY.md`
|
||||||
|
</output>
|
||||||
157
.planning/phases/06-consensus-export/06-02-PLAN.md
Normal file
157
.planning/phases/06-consensus-export/06-02-PLAN.md
Normal file
|
|
@ -0,0 +1,157 @@
|
||||||
|
---
|
||||||
|
phase: 06-consensus-export
|
||||||
|
plan: 02
|
||||||
|
type: execute
|
||||||
|
---
|
||||||
|
|
||||||
|
<objective>
|
||||||
|
Implement markdown export for discussions and projects.
|
||||||
|
|
||||||
|
Purpose: Enable users to export discussion history and consensus to shareable markdown documents (M7 milestone).
|
||||||
|
Output: Working /export command that generates and sends markdown files via Telegram.
|
||||||
|
</objective>
|
||||||
|
|
||||||
|
<execution_context>
|
||||||
|
~/.claude/get-shit-done/workflows/execute-phase.md
|
||||||
|
~/.claude/get-shit-done/templates/summary.md
|
||||||
|
</execution_context>
|
||||||
|
|
||||||
|
<context>
|
||||||
|
@.planning/PROJECT.md
|
||||||
|
@.planning/ROADMAP.md
|
||||||
|
@.planning/STATE.md
|
||||||
|
|
||||||
|
# Prior plan context:
|
||||||
|
@.planning/phases/06-consensus-export/06-01-SUMMARY.md
|
||||||
|
|
||||||
|
# Source files to reference:
|
||||||
|
@src/moai/core/models.py
|
||||||
|
@src/moai/core/services/discussion.py
|
||||||
|
@src/moai/core/services/project.py
|
||||||
|
@src/moai/bot/handlers/__init__.py
|
||||||
|
@src/moai/bot/handlers/commands.py
|
||||||
|
|
||||||
|
**Tech stack available:** python-telegram-bot, sqlalchemy
|
||||||
|
**Established patterns:** Service layer, handler registration, get_selected_project helper
|
||||||
|
|
||||||
|
**SPEC.md export format:**
|
||||||
|
```markdown
|
||||||
|
# {Project Name}
|
||||||
|
|
||||||
|
**Date:** {date}
|
||||||
|
**Models:** Claude, GPT, Gemini
|
||||||
|
**Discussions:** {count}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Discussion 1: {Question}
|
||||||
|
|
||||||
|
### Initial Responses (Open)
|
||||||
|
**Claude:**
|
||||||
|
> {response}
|
||||||
|
|
||||||
|
### Discussion (N rounds)
|
||||||
|
**Round 1:**
|
||||||
|
**Claude:** {response}
|
||||||
|
**GPT:** {response}
|
||||||
|
|
||||||
|
### Consensus
|
||||||
|
**Agreements:**
|
||||||
|
- point 1
|
||||||
|
|
||||||
|
**Disagreements:**
|
||||||
|
- **Topic:** {topic}
|
||||||
|
- Claude: {position}
|
||||||
|
```
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<tasks>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 1: Create exporter module</name>
|
||||||
|
<files>src/moai/core/exporter.py</files>
|
||||||
|
<action>
|
||||||
|
Create new file src/moai/core/exporter.py with:
|
||||||
|
|
||||||
|
1. Module docstring explaining markdown export functionality.
|
||||||
|
|
||||||
|
2. `export_discussion(discussion: Discussion) -> str` function:
|
||||||
|
- Format discussion as markdown following SPEC format
|
||||||
|
- Include question as heading
|
||||||
|
- Group messages by round, label round type (parallel = "Initial Responses", sequential = "Round N")
|
||||||
|
- Format each message as `**Model:** response`
|
||||||
|
- Include consensus section if consensus exists (agreements as bullets, disagreements with positions)
|
||||||
|
- Return markdown string
|
||||||
|
|
||||||
|
3. `export_project(project: Project, discussions: list[Discussion]) -> str` function:
|
||||||
|
- Header with project name, date, models list, discussion count
|
||||||
|
- Separator (---)
|
||||||
|
- Each discussion formatted via export_discussion()
|
||||||
|
- Separators between discussions
|
||||||
|
- Return full markdown string
|
||||||
|
|
||||||
|
4. Helper `_format_consensus(consensus: Consensus) -> str`:
|
||||||
|
- Format agreements as bullet list
|
||||||
|
- Format disagreements with topic and model positions
|
||||||
|
- Return formatted string or empty if no consensus
|
||||||
|
|
||||||
|
Use datetime.now().strftime("%Y-%m-%d") for date formatting.
|
||||||
|
</action>
|
||||||
|
<verify>`python -c "from moai.core.exporter import export_discussion, export_project"` succeeds</verify>
|
||||||
|
<done>Exporter module creates properly formatted markdown matching SPEC format</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 2: Create /export command handler</name>
|
||||||
|
<files>src/moai/bot/handlers/export.py, src/moai/bot/handlers/__init__.py, src/moai/bot/handlers/commands.py</files>
|
||||||
|
<action>
|
||||||
|
1. Create new file src/moai/bot/handlers/export.py with:
|
||||||
|
- Import exporter functions, services, telegram types
|
||||||
|
- `export_command(update, context)` handler:
|
||||||
|
- Get selected project (error if none)
|
||||||
|
- Parse args: no args = export active discussion, "project" = export full project
|
||||||
|
- For discussion export:
|
||||||
|
- Get active discussion (error if none)
|
||||||
|
- Call export_discussion()
|
||||||
|
- Send as document: `update.message.reply_document(io.BytesIO(md.encode()), filename=f"{project.name}-discussion.md")`
|
||||||
|
- For project export:
|
||||||
|
- Get all discussions for project via list_discussions()
|
||||||
|
- Fetch each with full eager loading via get_discussion()
|
||||||
|
- Call export_project()
|
||||||
|
- Send as document with filename `{project.name}-export.md`
|
||||||
|
- Use io.BytesIO for in-memory file, import io module
|
||||||
|
|
||||||
|
2. Update handlers/__init__.py:
|
||||||
|
- Import export_command from export module
|
||||||
|
- Register `CommandHandler("export", export_command)`
|
||||||
|
|
||||||
|
3. Update HELP_TEXT in commands.py, Output section:
|
||||||
|
`/export` - Export current discussion as markdown
|
||||||
|
`/export project` - Export entire project as markdown
|
||||||
|
</action>
|
||||||
|
<verify>Bot responds to /export with a markdown document attachment</verify>
|
||||||
|
<done>/export sends discussion markdown, /export project sends full project markdown as Telegram documents</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
</tasks>
|
||||||
|
|
||||||
|
<verification>
|
||||||
|
Before declaring plan complete:
|
||||||
|
- [ ] `ruff check src/moai/core/exporter.py src/moai/bot/handlers/export.py`
|
||||||
|
- [ ] `python -c "from moai.core.exporter import export_discussion, export_project"` succeeds
|
||||||
|
- [ ] `python -c "from moai.bot.handlers.export import export_command"` succeeds
|
||||||
|
</verification>
|
||||||
|
|
||||||
|
<success_criteria>
|
||||||
|
|
||||||
|
- Exporter module generates SPEC-compliant markdown
|
||||||
|
- /export sends discussion as .md document
|
||||||
|
- /export project sends full project as .md document
|
||||||
|
- Help text updated
|
||||||
|
- No ruff errors
|
||||||
|
- Phase 6 complete (M6 + M7 milestones)
|
||||||
|
</success_criteria>
|
||||||
|
|
||||||
|
<output>
|
||||||
|
After completion, create `.planning/phases/06-consensus-export/06-02-SUMMARY.md`
|
||||||
|
</output>
|
||||||
Loading…
Add table
Reference in a new issue