Lossless Changelog
component

Firm-Scoped IO System: Complete Implementation

This release completes the firm-scoped IO system, enabling private, firm-specific configurations, inputs, outputs, and exports. The system allows each firm (e.g.

Changelog - 2025-12-02 (#1)

Firm-Scoped IO System: Complete Implementation

Overview

This release completes the firm-scoped IO system, enabling private, firm-specific configurations, inputs, outputs, and exports. The system allows each firm (e.g., Hypernova Capital) to maintain their own branded templates, scorecards, outlines, and deal data isolated from the shared codebase—critical for multi-tenant deployments and keeping client data private.


Architecture: Firm-Scoped Directory Structure

The firm-scoped IO system uses the following directory structure:

io/
└── {firm}/                           # e.g., "hypernova"
    ├── configs/
    │   └── brand-{firm}-config.yaml  # Firm-specific brand styling
    ├── templates/
    │   ├── outlines/                 # Firm-specific content outlines
    │   │   ├── direct-early-stage-12Ps.yaml
    │   │   └── lpcommit-emerging-manager.yaml
    │   └── scorecards/               # Firm-specific evaluation scorecards
    │       └── direct-early-stage-12Ps/
    │           └── hypernova-early-stage-12Ps.yaml
    └── deals/
        └── {deal}/                   # e.g., "Blinka"
            ├── {deal}.json           # Deal configuration
            ├── inputs/               # Pitch decks, datarooms
            ├── outputs/              # Versioned memo artifacts
            │   └── {Deal}-v0.0.x/
            │       ├── 0-deck-analysis.json
            │       ├── 1-research.json
            │       ├── 2-sections/
            │       ├── 4-final-draft.md
            │       └── state.json
            ├── exports/              # Branded HTML/PDF exports
            │   ├── dark/
            │   └── light/
            └── assets/               # Deal-specific assets (logos)

Key Benefits

  1. Privacy: Firm-specific configs and deal data stay in io/ (gitignored or private submodule)

  2. Multi-Tenant: Multiple firms can use the same codebase with isolated configurations

  3. Backward Compatible: Legacy output/, data/, templates/ paths still work

  4. Auto-Detection: System auto-detects firm context from input file paths


Changes by Module

1. Brand Configuration (src/branding.py)

Purpose: Load brand configs from firm-scoped paths first.

Changes:

  • Added firm parameter to BrandConfig.load() method

  • New priority order for brand config lookup:

    1. config_path if explicitly provided

    2. io/{firm}/configs/brand-{name}-config.yaml (firm-scoped)

    3. templates/brand-configs/brand-{name}-config.yaml (shared)

    4. brand-{name}-config.yaml (root directory, legacy)

    5. Default Hypernova config (fallback)

  • Updated list_available_brands() to search firm-scoped configs first

Example:

PYTHON
# Now checks io/hypernova/configs/ first
brand = BrandConfig.load(brand_name="hypernova", firm="hypernova")

2. Scorecard Loader (src/scorecard_loader.py)

Purpose: Load evaluation scorecards from firm-scoped paths first.

Changes:

  • Added firm parameter to get_scorecards_dir(), find_scorecard_file(), load_scorecard()

  • New priority order for scorecard lookup:

    1. io/{firm}/templates/scorecards/ (firm-scoped)

    2. templates/scorecards/ (shared)

  • Updated cache key to include firm for proper isolation

  • Updated load_scorecard_for_state() to extract firm from state

Example:

PYTHON
# Checks io/hypernova/templates/scorecards/ first
scorecard = load_scorecard("hypernova-early-stage-12Ps", firm="hypernova")

3. Export Branded CLI (cli/export_branded.py)

Purpose: Export memos to firm-scoped exports directory with auto-detection.

Major Changes:

  • Added --firm, --deal, --version CLI arguments

  • Auto-detects firm from input file path pattern: io/{firm}/deals/{deal}/...

  • Exports to io/{firm}/deals/{deal}/exports/{mode}/ when firm-scoped

  • Passes firm to BrandConfig.load() for firm-scoped brand lookup

  • Updated company data lookup to check firm-scoped paths first

New CLI Usage:

BASH
# Explicit firm/deal (recommended)
python cli/export_branded.py --firm hypernova --deal Blinka --mode dark --pdf

# Auto-detection from path (just as good)
python cli/export_branded.py io/hypernova/deals/Blinka/outputs/Blinka-v0.0.2/4-final-draft.md --brand hypernova

# Legacy still works
python cli/export_branded.py output/Company-v0.0.1/4-final-draft.md

Auto-Detection Output:

Auto-detected firm-scoped path: hypernova/Blinka
  Exporting to: io/hypernova/deals/Blinka/exports/dark

4. Workflow (src/workflow.py)

Purpose: Ensure human_review() saves artifacts to firm-scoped paths.

Changes:

  • Updated human_review() function to use firm-aware path resolution

  • Uses resolve_deal_context() when firm is provided

  • Creates output directory in firm-scoped location


5. Artifacts (src/artifacts.py)

Purpose: Save/load artifacts from firm-scoped paths.

Changes:

  • Added firm parameter to save_deck_analysis_artifacts()

  • Added firm parameter to load_existing_section_drafts()

  • Uses resolve_deal_context() for firm-aware path resolution

  • Passes firm to create_artifact_directory()


6. Agent Updates

All agents now support firm-scoped output paths:

src/agents/deck_analyst.py

  • Extracts firm from state

  • Passes firm to save_deck_analysis_artifacts()

src/agents/writer.py

  • Uses resolve_deal_context() for firm-aware output directory

  • Creates artifact directory with create_artifact_directory(company, version, firm=firm)

src/agents/research_enhanced.py

  • Uses firm-aware VersionManager initialization

  • Creates artifact directory with firm parameter

src/agents/validator.py

  • Simplified to use get_latest_output_dir(company, firm=firm)

  • Removed redundant version manager logic

src/agents/perplexity_section_researcher.py

  • Added firm-aware fallback when creating new output directories

  • Uses create_artifact_directory() with firm parameter

src/agents/dataroom/analyzer.py

  • Updated _get_or_create_output_dir() to accept firm parameter

  • Uses firm-aware path resolution throughout


7. Other CLI Tools Updated

All CLI tools now support --firm and --deal flags:

CLI ToolChanges
cli/improve_section.pyAdded --firm, --deal flags with auto-detection
cli/score_memo.pyAdded --firm, --deal flags with auto-detection
cli/refocus_section.pyAdded --firm, --deal flags with path resolution
cli/recompile_memo.pyAdded --firm, --deal flags with auto-detection

Files Changed Summary

Modified Files (16)

FilePurpose
src/branding.pyFirm-scoped brand config loading
src/scorecard_loader.pyFirm-scoped scorecard loading
src/artifacts.pyFirm-scoped artifact saving/loading
src/workflow.pyFirm-aware human_review()
src/agents/deck_analyst.pyPass firm to artifact saving
src/agents/writer.pyFirm-aware output directory
src/agents/research_enhanced.pyFirm-aware artifact creation
src/agents/validator.pySimplified firm-aware path resolution
src/agents/perplexity_section_researcher.pyFirm-aware fallback directory creation
src/agents/dataroom/analyzer.pyFirm-aware output directory
cli/export_branded.pyAuto-detection, firm-scoped exports
cli/improve_section.pyAdded --firm/--deal flags
cli/score_memo.pyAdded --firm/--deal flags
cli/refocus_section.pyAdded --firm/--deal flags
cli/recompile_memo.pyAdded --firm/--deal flags
context-vigilance/Firm-and-Deal-based-File-Organization-System.mdUpdated progress

New Files (2)

FilePurpose
context-vigilance/Fix-Firm-Scoped-Output-Paths.mdPlanning document for this work
context-vigilance/MemoPop-Landing-Page-Sepcification.mdProduct landing page spec

Deleted Files (Moved to io/hypernova/)

These firm-specific files were moved from shared templates to io/hypernova/:

Original LocationNew Location
templates/brand-configs/brand-hypernova-config.yamlio/hypernova/configs/brand-hypernova-config.yaml
templates/outlines/direct-early-stage-12Ps.yamlio/hypernova/templates/outlines/direct-early-stage-12Ps.yaml
templates/outlines/lpcommit-emerging-manager.yamlio/hypernova/templates/outlines/lpcommit-emerging-manager.yaml
templates/scorecards/direct-early-stage-12Ps/hypernova-early-stage-12Ps.yamlio/hypernova/templates/scorecards/...
templates/scorecards/lp-commits_emerging-managers/hypernova-scorecard.yamlio/hypernova/templates/scorecards/...
templates/hypernova-reference.docxio/hypernova/templates/hypernova-reference.docx

Usage Examples

Complete Workflow with Firm-Scoped IO

BASH
# 1. Generate memo (firm-scoped outputs)
python -m src.main "Blinka" --firm hypernova

# 2. Improve a section
python cli/improve_section.py --firm hypernova --deal Blinka "Team"

# 3. Export to branded PDF
python cli/export_branded.py --firm hypernova --deal Blinka --mode dark --pdf

# 4. Score the memo
python cli/score_memo.py --firm hypernova --deal Blinka

Auto-Detection (No --firm needed)

When input path contains io/{firm}/deals/{deal}/, the system auto-detects:

BASH
# Auto-detects hypernova/Blinka from path
python cli/export_branded.py io/hypernova/deals/Blinka/outputs/Blinka-v0.0.2/4-final-draft.md --brand hypernova

# Output:
# Auto-detected firm-scoped path: hypernova/Blinka
#   Exporting to: io/hypernova/deals/Blinka/exports/dark

Testing & Validation

Tested Scenarios

  • Export auto-detects firm from io/ path structure

  • Exports go to io/{firm}/deals/{deal}/exports/{mode}/

  • Brand config loads from io/{firm}/configs/

  • Scorecard loads from io/{firm}/templates/scorecards/

  • Legacy paths (output/, data/, templates/) still work

  • Full pipeline generates to firm-scoped outputs

  • PDF export works with firm-scoped paths

Test Results

# Blinka memo export test
Auto-detected firm-scoped path: hypernova/Blinka
  Exporting to: io/hypernova/deals/Blinka/exports/dark

✓ Loading brand config: io/hypernova/configs/brand-hypernova-config.yaml
✓ Brand: Hypernova Capital
✓ HTML (dark): Blinka-v0.0.2-draft.html (87.8 KB)
✓ PDF: Blinka-v0.0.2-draft.pdf (91.3 KB)

Output directory: io/hypernova/deals/Blinka/exports/dark

Remaining Work

Documentation Updates Needed

  • Update README.md with firm-scoped IO structure

  • Create io/README.md with setup instructions

  • Update CLAUDE.md with new path patterns

Future Enhancements

  • src/outline_loader.py - Check io/{firm}/templates/outlines/ first

  • Environment variable MEMO_DEFAULT_FIRM support in CLI tools

  • Firm-specific prompt templates in io/{firm}/templates/prompts/


Breaking Changes

None. All changes are backward compatible:

  • Legacy output/, data/, templates/ paths continue to work

  • --firm flag is optional; omitting it uses legacy behavior

  • Auto-detection only activates for io/ path patterns


Contributors

Implementation by Claude Code (Anthropic) with user guidance.