Portfolio

Portfolio workflows

Portfolio commands turn source lanes into connected ODPC, ODPS, ODPG, HTML, localization, and version outputs. The recommended workflow is to inspect and build one lane first, then add the other lanes when the source extraction and generated shape look right.

Source lane layout

Each lane represents a different evidence type. Keep source files close to the lane they support so the portfolio prompt can distinguish business goals, user demand, external or operational signals, and actual product candidates.

Foldersrecommended shape
source_docs/
  objectives/
  use-cases/
  signals/
  products/
generated/
  portfolio/

Inspect one lane first

portfolio intake is the most important debugging command in the portfolio workflow. Start with one lane, not the whole bundled portfolio. It reads source files, detects file types, extracts text, masks personal data when enabled, applies prompt budgets, and reports what would be sent to the model. It does not call an LLM.

Recommended first checkone lane, no LLM call
open-data-products portfolio intake \
  --signals source_docs/signals/ \
  --config generation.config.yaml \
  --json

Use the lane that is easiest to verify manually. If you have product briefs, start with --products. If you have market evidence or operational observations, start with --signals. The goal is to confirm that the SDK sees the right files, extracts useful text, and reports the expected source count before any model call.

Other single-lane checksswap the lane, keep the pattern
open-data-products portfolio intake \
  --products source_docs/products/ \
  --config generation.config.yaml \
  --json

open-data-products portfolio intake \
  --objectives source_docs/objectives/ \
  --config generation.config.yaml \
  --json

open-data-products portfolio intake \
  --use-cases source_docs/use-cases/ \
  --config generation.config.yaml \
  --json

Build one lane first

After one-lane intake looks right, build a small workspace from that same lane. This is the safest first LLM-backed portfolio run because the output is easier to inspect. Use --strict-validation when invalid generated portfolio artifacts should fail the command instead of completing with warnings.

Recommended first buildone lane, small output
open-data-products portfolio build \
  --signals source_docs/signals/ \
  --config generation.config.yaml \
  --output generated/portfolio-signals/ \
  --strict-validation \
  --json

open-data-products portfolio explain generated/portfolio-signals/ --json
open-data-products validate generated/portfolio-signals/odpc/catalog.yaml
open-data-products validate generated/portfolio-signals/odpg/graph.yaml

Review the generated HTML and YAML before adding more lanes. Look for duplicated concepts, vague product names, weak source evidence, or relationships that do not match the source material. Fix the source folder or prompt configuration while the workspace is still small.

Build the combined workspace

Use the bundled all-lanes command only after one-lane intake and one-lane build have proved the workflow. The combined run is useful for the final connected portfolio, but it is harder to debug because objectives, use cases, signals, and products can all affect the generated catalog and graph.

All lanesconnected portfolio output
open-data-products portfolio intake \
  --objectives source_docs/objectives/ \
  --use-cases source_docs/use-cases/ \
  --signals source_docs/signals/ \
  --products source_docs/products/ \
  --config generation.config.yaml \
  --json
Combined buildafter lane-level review
open-data-products portfolio build \
  --objectives source_docs/objectives/ \
  --use-cases source_docs/use-cases/ \
  --signals source_docs/signals/ \
  --products source_docs/products/ \
  --config generation.config.yaml \
  --output generated/portfolio/ \
  --strict-validation \
  --json

Lifecycle commands

After buildrefresh, sync, localize, render
open-data-products portfolio refresh generated/portfolio/
open-data-products portfolio refresh generated/portfolio/ --all-sources

open-data-products portfolio sync generated/portfolio/

open-data-products portfolio localize generated/portfolio/ \
  --languages "fi,sv,ar,vi" \
  --provider claude \
  --model claude-sonnet-4-5

open-data-products portfolio render generated/portfolio/
open-data-products portfolio explain generated/portfolio/ --json

What gets created

OutputPurposeReview action
index.htmlHuman review page for the portfolio workspace.Open in a browser and review value narrative, product grouping, evidence, and gaps.
portfolio.yamlStructured portfolio state.Use as the workspace-level source for refresh, sync, render, and explain.
odpc/catalog.yamlCatalog-level ODPC output.Validate and inspect catalog contents before publishing or reuse.
odpc/fragments/Generated objectives, use cases, signals, and product references.Review IDs, names, evidence links, and duplicates.
odpg/graph.yamlGraph relationship context between objectives, products, use cases, signals, and KPIs.Run graph summary, traversal, and agent-context commands.
odps/products/ODPS product drafts created for portfolio candidates.Validate product files and refine product details before handover.

Supported source inputs

LanePurposeSupported inputs
--objectivesBusiness objectives, outcomes, strategy notes, executive targets.Markdown, text, YAML, JSON, EML, DOCX, PPTX, XLSX, PDF with embedded text, CSV, and Outlook MSG when installed with pip install "open-data-products[email]".
--use-casesUse cases, user journeys, decision needs, stakeholder workflows.
--signalsMarket signals, operational signals, risks, quality evidence, usage evidence.
--productsExisting products, candidate products, product notes, product briefs.

Debug intake first

When generated portfolio output looks incomplete, inspect the intake JSON before changing the prompt. Check sourceCounts, sourceExtraction.skippedSources, per-source status, sourceBudget.omittedChunkCount, sourcePrivacy.enabled, and warnings.

Important: image-only PDFs, images, hidden spreadsheet sheets, hidden slides, PowerPoint notes, and email attachments are not silently extracted by the base workflow. Put required evidence into supported text-bearing source files.

Common portfolio fixes

Finding in intake JSONMeaningPractical fix
status: skippedThe SDK detected the file but did not extract usable text.Check the warning, install optional extras if needed, or convert the content into supported text-bearing input.
status: emptyThe file was readable but produced no extracted text.Check whether the source contains only images, hidden data, comments, speaker notes, or attachments.
status: reducedText was extracted but not all chunks fit into the configured prompt budget.Split the source, reduce irrelevant content, or raise maxPromptChars only when the selected model can handle it.
sourcePrivacy.enabled: truePersonal data masking changed values before prompt construction.Review replacement counts and keep masking enabled for external providers unless the workflow is controlled and local-only.