Scorecard Integration into Workflow
This release adds automatic 12Ps scorecard integration to the memo workflow. Previously, the scorecard evaluator generated detailed scores in `5-scorecard/12Ps-scorecard.
Changelog - 2025-12-06 (#2)
Scorecard Integration into Workflow
Overview
This release adds automatic 12Ps scorecard integration to the memo workflow. Previously, the scorecard evaluator generated detailed scores in 5-scorecard/12Ps-scorecard.md, but this ran AFTER the writer created section 8—meaning the scorecard data never made it into the final draft. Now, a new integrate_scorecard workflow step automatically merges the scorecard into section 8 and reassembles the final draft.
Problem
The workflow sequence had a timing issue:
writer (creates section 8 "Scorecard Summary") → ... → scorecard_evaluator (generates 5-scorecard/12Ps-scorecard.md)Issues:
Section 8 was written as a placeholder without actual scorecard data
The detailed 12Ps evaluation was generated but stored separately in
5-scorecard/Users had to manually copy the scorecard into the final document
The final draft shipped without the core investment evaluation
Solution: integrate_scorecard Workflow Node
Added a new workflow node that runs after scorecard evaluation:
scorecard → integrate_scorecard → conditional(should_continue) → finalize/human_reviewWhat integrate_scorecard() Does
Locates scorecard file at
{output_dir}/5-scorecard/12Ps-scorecard.mdFinds section 8 by pattern
{output_dir}/2-sections/08-*.mdor*scorecard*.mdReplaces section 8 content with the full scorecard
Reassembles final draft from all sections in order
Preserves header (logo/trademark) if present from existing draft
Function Implementation
def integrate_scorecard(state: MemoState) -> dict:
"""
Integrate the 12Ps scorecard into section 8 and reassemble final draft.
"""
from .utils import get_latest_output_dir
company_name = state["company_name"]
firm = state.get("firm")
output_dir = get_latest_output_dir(company_name, firm=firm)
# Check for scorecard file
scorecard_file = output_dir / "5-scorecard" / "12Ps-scorecard.md"
if not scorecard_file.exists():
return {"messages": ["Scorecard integration skipped: no scorecard file"]}
# Find and replace section 8
sections_dir = output_dir / "2-sections"
for f in sections_dir.glob("08-*.md"):
scorecard_content = scorecard_file.read_text()
f.write_text(scorecard_content)
print(f" ✓ Integrated scorecard into {f.name}")
break
# Reassemble final draft preserving header
final_draft_path = output_dir / "4-final-draft.md"
content = ""
# Preserve logo if present
if final_draft_path.exists():
existing = final_draft_path.read_text()
first_line = existing.split('\n')[0]
if first_line.startswith('!['):
content = first_line + '\n\n'
# Assemble all sections
for section_file in sorted(sections_dir.glob("*.md")):
if section_file.name == "header.md":
continue
content += section_file.read_text() + '\n\n'
final_draft_path.write_text(content)
return {"messages": [f"Scorecard integrated ({len(content.split())} words)"]}Workflow Changes
Node Addition
# In build_workflow()
workflow.add_node("integrate_scorecard", integrate_scorecard)Edge Updates
Before:
workflow.add_edge("validate", "scorecard")
workflow.add_conditional_edges("scorecard", should_continue, {...})After:
workflow.add_edge("validate", "scorecard")
workflow.add_edge("scorecard", "integrate_scorecard")
workflow.add_conditional_edges("integrate_scorecard", should_continue, {...})Updated Flow Sequence
Deck Analyst → Research → Section Research → Draft → Trademark → Socials → Links
→ Visualizations → Citations → TOC → Revise Summaries → Citation Validator
→ Fact Check → Validate → Scorecard → Integrate Scorecard → Finalize/Human ReviewFiles Changed
| File | Change |
src/workflow.py | Added integrate_scorecard() function (~80 lines) |
src/workflow.py | Added integrate_scorecard node to workflow graph |
src/workflow.py | Updated edges: scorecard → integrate_scorecard → conditional |
src/workflow.py | Updated workflow sequence comment |
Impact
Before This Change
Final draft section 8 contained placeholder text without actual scores
Detailed scorecard lived in separate file
5-scorecard/12Ps-scorecard.mdUsers had to manually copy scorecard content into final draft
Export/review pipeline shipped incomplete memos
After This Change
Section 8 contains the full 12Ps evaluation with all dimension scores
Final draft is automatically reassembled with integrated scorecard
Zero manual intervention required for complete memos
Scorecard data flows directly into human review/finalization
Example Output
✓ Integrated scorecard into 08-12ps-scorecard-summary.md
✓ Reassembled final draft: 4,832 wordsTesting
Verification Command
# Verify workflow compiles
python -c "from src.workflow import build_workflow; w = build_workflow(); print('✓ Workflow compiles')"Expected Behavior
After running memo generation:
5-scorecard/12Ps-scorecard.mdcontains detailed evaluation2-sections/08-*.mdcontains same content as scorecard file4-final-draft.mdincludes full scorecard in section 8
Related Documentation
context-vigilance/12Ps-Framework-for-Due-Diligence.md- 12Ps framework specificationchangelog/2025-12-06_01.md- Dimension-grouped questions (same session)templates/scorecards/- Scorecard template definitions
Contributors
Implementation by Claude Code (Anthropic) with user guidance.