for the people who run the book

The portfolio platform that thinks alongside you.

The spreadsheets run themselves now. Your time is yours again. An AI-native portfolio platform for institutional investors — built by a practitioner with two decades inside the work it automates, not by a software vendor guessing at it.

~/front-officelive
PortfoliFLOW front office
Front office · Minathena Capital · synthetic demo data
01  /  the shift

Operational work is done by the machine. Frees up your time to find even better ways to allocate capital.

No more re-keying reports, reconciling cash flows, or checking allocation limits by hand. PortfoliFLOW automates the operational layer — extraction, monitoring, analytics, controlling — so a small team's attention goes where it actually compounds: the strategy, the selection, and the sharpest decisions about where capital should sit. The kind of per-investment analysis that used to take a day, produced for every holding, on demand:

~/investments/Q
Investment Q — total return, cash flows & NAV, multiples
Total return · cash flows & NAV · TVPI & DPI — synthetic demo data
~/investments/R
Investment R — total return, cash flows & NAV, multiples
The same triplet, every holding · synthetic demo data
02  /  inside the platform

What it replaces.

A guided tour. For each area the question isn't only what it shows — it's which manual job it quietly removes.

front office

Your whole book, the moment you log in.

replaces the master workbook

KPIs, invested capital against NAV, cash flows and NAV-by-fund — the operational cockpit that used to be a spreadsheet someone refreshed by hand every Monday.

~/front-office/overviewlive
Front office overview
key metrics

Every investment, at a glance.

replaces the per-fund tracker tabs

NAV, annualised return and Sharpe for each holding, with a live sparkline. Sixteen holdings, one screen, always current.

~/statistics/key-metrics
Key metrics per investment
correlation

How your investments actually move together.

replaces a correlation matrix nobody updates

Sixteen holdings, one heatmap, recomputed on the live book. Concentration you can see before it becomes concentration you regret.

~/risk/correlation
Correlation matrix
benchmarks & attribution

Did each manager beat its benchmark?

replaces a benchmarking exercise run once a year

Every investment mapped to its asset-class benchmark — 16 of 16 covered, a median excess of +8.1% p.a., a 75% hit rate. Coverage and excess, not anecdotes.

~/benchmarks/attribution
Benchmarks and attribution
manager selection

In aggregate, do your managers beat the market?

replaces a question you could only answer by feel

Own investments per asset class, NAV-weighted, against the asset-class benchmark. +28.9% and +20.8% on the infrastructure sleeves — selection, measured.

~/benchmarks/composites
Asset-class composites versus benchmarks
03  /  reporting

The report writes itself.

The quarterly investor pack — generated from the live book, not assembled in slides the night before.

~/investor/portfolio-reviewlive
Portfolio review report
Portfolio review · NAV, IRR, TVPI, DPI · region / vintage / sector · synthetic demo data
report scraper

Incoming reports, read for you.

replaces reading a 40-page manager report line by line

Hand the scraper a manager's quarterly PDF and your order list — NAV, TVPI, DPI, Net IRR, capital called, whatever you track — defined once as a table of keywords. It finds every line, derives what moved performance and which deals closed in the period, and rates its own confidence in each. Every value carries a page-level source citation, so a human or a machine can verify it. Once imported, the extracted values are available for analysis inside the platform and stored in the database for future reference.

~/front-office/report-scraper
Report Scraper reading the Unicorn Ventures Q3 2025 report — NAV, Net IRR, TVPI, DPI and capital called extracted with page-level sources and confidence
04  /  better decisions

Everyone knows portfolio optimisation. Almost no one runs it in production.

PortfoliFLOW runs it continuously, on the real portfolio — and forecasts limit breaches before they happen, so nothing surprises you at quarter-end.

portfolio optimisation

The efficient frontier, on your live book.

replaces the annual optimisation slide

A tangency portfolio at a Sharpe of 2.02 against a current 1.18 — a standing view you can act on, not a one-off study.

~/optimisation/efficient-frontier
Efficient frontier
investment limits

Limits, checked for you.

replaces the quarterly manual limit check

Every class against its cap — OK or breach, with headroom in euros. Infra-equity is €10.1m over: flagged, not discovered later.

~/limits
Investment limits
limits · forecast

See breaches before they happen.

replaces finding out at quarter-end

The same coverage, projected forward to 2030. Trajectories drifting toward a cap show up while you can still do something about it.

~/limits/coverage-forecastforecast
Coverage forecast

And when the board asks whether active allocation actually earned its keep:

~/saa/hypothetical
SAA hypothetical — actual versus passive SAA
Actual +123.5% vs SAA × benchmark +49.9% — allocation effect +73.7pp · synthetic demo data

The result isn't just less work. It's higher returns.

05  /  shirley

Not a chatbot. A colleague.

Shirley is an agent — she reaches the same data the platform holds, calls the same tools you do, and comes back with an answer and a recommendation. Type to her, call her, send a voice note, or show her a document — she even reads a term sheet you photographed at a conference and tells you whether it fits.

tools she calls, herself get_portfolio_limits run_saa_hypothetical analyse_image render_chart
Meet Shirley →
06  /  built for institutions

Built to institutional standards.

Architecture decisions are recorded before code is written — after Nygård — and aligned to ISO 25010, arc42 and CERT Python. Every action is audit-logged; tenants are separated at the database with row-level security; the system is designed to DORA resilience principles and built to support your own DORA obligations.

Architecture & docs →
07  /  for whom

Who it's for.

institutional

Pension funds

Running diversified institutional portfolios under real regulatory scrutiny.

managers

Asset & investment managers

Boutique and mid-size houses that need institutional rigour without an institutional headcount.

allocators

Family offices & allocators

Anyone running a multi-asset institutional book who has outgrown the spreadsheet.

01  /  what she can do

Talk to her. Show her. Ask her.

voice

Just call her and talk

In the car, between meetings, on the move — call her and speak, or send a voice note. She answers out loud and in text, with the charts and analysis rendered alongside.

vision

Show her a document

Photograph a term sheet, a chart, a page. She reads the image, weighs it against your book, and tells you what it means.

tools

The same tools you have

She pulls series, runs the platform's analyses, renders charts and reads the press — herself, in the same turn.

anywhere

Desk and Telegram

The same colleague on whichever surface the work is happening — at the screen, or in your pocket at a conference.

02  /  a real session

She answers — with the numbers.

One real exchange at the desk. She fetches, computes, and commits to a recommendation.

shirley · sessionagent
We've got a €40m infra-equity call landing in Q3. Against our end-2030 limits, does that tip anything into breach — and if so, what would you trim?
callingget_portfolio_limitslist_investmentsget_investment_data

Yes — and not by a little. Infra-equity is already projected about €10m over its 5% cap by end-2030, so a €40m call takes it to roughly −€50m of headroom.

The honest part: that cap is class-specific. Nothing you trim elsewhere creates room under it — funding the call only pushes infra-equity further over. So the real choices are three:

  1. Raise the infra-equity cap in the SAA and document the rationale — defensible if infra is a deliberate overweight.
  2. Offset within the class — secondary out ~€50m of existing infra-equity so net exposure stays inside 5%.
  3. Hold the call — if neither fits, it breaches policy and shouldn't clear without sign-off.

You do have cash to raise, by the way: gov-bonds DM and real estate are both over their caps already, so trimming those frees capital without opening new breaches. Want me to model 1 and 2 side by side?

Good. The board thinks we'd have done just as well passively holding the SAA weights. Settle it.
callingrun_saa_hypotheticalrender_chart

Not quite — and it's worth showing them exactly why. Held passively against benchmarks, the SAA weights would have returned +49.9% over the period. Your actual book did +123.5%. That gap — an allocation effect of +73.7pp — is selection and timing earning their fee, not luck.

~/saa/hypotheticalrendered
SAA hypothetical rendered by Shirley

Crimson is your actual book; the dotted line is the SAA held passively; the shaded band is the outperformance. That's the slide for the board.

03  /  she reads what you show her

A photo from the conference floor.

Shirley is always on — at your desk, on the move, pulled up mid-meeting. You're at a conference, someone pitches a fund, you photograph the term sheet and send it over. She reads the image, pulls your live book in the same turn, and gives you a straight answer — not "it depends" — before you talk to them again.

in one turn, she analyse_image get_portfolio_summary get_portfolio_limits
Shirleybot
What would you like to work on today?
At the investor conference — just met someone raising a new fund, early-stage “unicorn” ventures. Photographed the key terms. Could it fit our portfolio?
Fund III term sheet photographed at the conference
Got it — early-stage venture, solid record. Pulled your book: AUM €1.08bn · IRR 5.39% · TVPI 1.40x · 16 holdings.
Your SAA is Conservative Multi-Strategy and you're already in breach on 8 of 18 classes. A €750m early-stage venture fund piles risk exactly where you have the least headroom.
My read: compelling story, wrong fit for this book right now. Want the one-paragraph version to use at the booth?
Shirley on Telegram · synthetic demo data
04  /  where the numbers come from

She orchestrates. The code computes.

Role
orchestrate · coordinate
Never
no analysis · no arithmetic
Numbers
deterministic, auditable code

Shirley is an AI — but her job is narrow and deliberate: she orchestrates, communicates and coordinates. She picks the right tool, runs it, and tells you what came back. She never performs the analysis herself, and she never does the arithmetic.

The reason is auditability. A language model is non-deterministic by construction — ask it the same question twice and the wording, sometimes even the number, can drift. An institutional book cannot rest on that. So every figure Shirley reports — every IRR, every limit check, every allocation effect — is produced by the same deterministic, version-controlled analytics code the platform runs everywhere else: pinned in tests, inspectable line by line. Shirley reads the result back to you; she does not invent it.

That is the line between her and the general-purpose "AI agents" shipped by the large model providers. There, the model is the calculator. Here, the model is the colleague who knows which calculator to reach for — and the numbers themselves come from code an auditor can read.

01  /  principles

Decisions before code.

Two rules govern everything else. They are not aspirations on a slide — each is enforced mechanically, in the test suite or the import graph.

Discipline
ADR-first (after Nygård)
Analytics core
DB-free · framework-free · UI-free

Every architecturally significant decision is captured in a numbered Architecture Decision Record before the code lands. ADR bodies are immutable: a later decision supersedes an earlier one through a new record, never by editing history. The result is a traceable decision log an auditor can read, rather than a snapshot they have to take on faith.

The analytics core carries no database, no web framework and no UI. It takes arrays and DataFrames in and returns typed result objects — so the mathematics can be audited in isolation, and numerical output is pinned in tests to a tolerance of 1e-12.

02  /  the shape of the codebase

One language. One direction.

PortfoliFLOW is pure Python, end to end — web framework, async database access, analytics, the operator CLI, the AI tool layer and the Telegram bot. No second runtime, no JavaScript build pipeline, no client-side SPA. One mental model, one test harness.

Runtime
Python 3.11+
Web UI
server-rendered Jinja2 + HTMX over ASGI
Imports
directed graph, strictly one-way
Cycles
treated as a design error.

The codebase enforces a layered dependency graph. Lower layers know nothing of the layers above them; modules never reach sideways into sibling modules — anything shared lives in a layer they can both import from. The presentation layer is kept thin on purpose: routing, rendering and request shaping only, with no calculations and no schema knowledge.

portfoliflow import-graph
surfaces ......... web · bot · cli
   modules ........ feature units
   services ....... integrations + logic
   analytics ...... pure · DataFrames in
      core ....... orm · repositories
_

The heuristic that keeps the boundary honest: any function that computes, queries or transforms data must be callable in a unit test without instantiating the web app. Regression tests guard the seams — for instance, the web layer may not import the ORM directly or bypass the repository pattern. If it tries, the build fails.

03  /  modular by construction

It grows without breaking what works.

New capability is added, not woven in. Each module is a self-contained unit discovered through a single registry seam — so the system extends without destabilising what is already running.

Module
BaseModule subclass
Discovery
ModuleRegistry, by decorator
AI tools
typed ToolRegistry, same pattern
Cost to add
new files + ~3 lines.

Adding a feature means creating new files and appending at most a few lines to existing ones — the registry finds the rest. The same single-seam pattern governs the tools the AI assistant can call, so the surface, the module layer and the tool layer can each be tested, mocked or replaced in isolation.

The discipline is deliberately conservative: methods are implemented only where a concrete consumer already needs them. No speculative cross-module APIs, no premature platforming — capability follows demand.

04  /  isolation & access

Tenants are separated by the database, not by hope.

Multi-tenant and multi-user from the schema upward. Isolation is enforced where it cannot be forgotten — inside PostgreSQL itself — rather than re-implemented in every query by every developer.

Isolation
row-level security (RLS)
Connection
unprivileged app role
Routing
per-tenant, by subdomain
Access
owner · member · auditor (RBAC)

Every domain table carries a tenant_id. Each request opens a connection on an unprivileged application role and sets the tenant as the first statement of the transaction; PostgreSQL then filters every subsequent query. Application code never writes WHERE tenant_id = … — and because the request role is unprivileged, it cannot bypass the policy even if it tried. The superuser connection is reserved for migrations and bootstrap, and never serves a request.

On top of that sits session-cookie authentication with argon2 password hashing and CSRF-protected mutations, a three-role permission model, a separate platform-operations tenant, and an append-only audit log that records every action without gaps.

05  /  the stack

The machine underneath.

A small, modern, boring-on-purpose stack. Nothing exotic to operate; every component chosen so it can be reasoned about, tested and handed over. Every runtime dependency is open source — there is no proprietary database, framework or paid runtime in the build.

Web
FastAPI · Uvicorn · Jinja2 · HTMX
Data
PostgreSQL 16 · SQLAlchemy 2 (async) · asyncpg · Alembic
Analytics
pandas · NumPy · SciPy · Plotly
Platform
Pydantic 2 · Typer · httpx · argon2-cffi
AI
OpenAI-compatible client · provider-agnostic · typed Tool Registry
Deploy
Podman / Docker · Caddy

Persistence goes through a per-aggregate repository pattern — routes and services never touch the ORM directly — and schema changes flow only through Alembic migrations, forward-only, never create_all. Postgres runs as a local container, so no host-level database install is required to stand the system up.

portfoliflow status
analytics purity ...... enforced by tests
layer boundaries ...... guarded by tests
audit logging ......... gapless
tenant isolation ...... row-level security
migrations ............ forward-only
_
06  /  the SAA engine

Transparent inputs, auditable maths.

A worked example of the analytics core in practice: forward-looking expectations and weight bounds per asset class, with an editable correlation matrix — the inputs behind the optimisation and the SAA hypotheticals. Nothing hidden, every assumption on the table.

~/saa/inputs
SAA asset-class inputs
~/saa/correlation
SAA asset-class correlation matrix
Strategic asset allocation engine · synthetic demo data
07  /  standards & honest claims

Built to be reviewed — and precise about what that means.

The build is aligned to ISO 25010, arc42 and CERT Python. The combination of an immutable ADR log, mechanically enforced layer boundaries and an RLS-isolated data model is what lets an external reviewer trust the system's outputs before reading a single line of business logic.

On DORA we are deliberately precise. PortfoliFLOW does not claim to be "DORA-compliant" — that obligation rests with the financial entity, not its software. It is designed to DORA resilience principles and built to support those obligations as a well-documented ICT service.

The same precision applies to openness: the runtime stack is built entirely on open-source components, and the platform foundations — the layered architecture, the registry framework, the pure analytics core, the multi-tenant data layer and the AI tool framework — are designed for an eventual open-core release.

08  /  deployment & data residency

Run it where your policy requires.

option a

Local

On a single workstation, for evaluation or a one-person desk.

option b

On-premise

Inside your own infrastructure, behind your own controls and network policy.

option c

SaaS

Zero setup. Hosted on EU servers within the GDPR jurisdiction, in ISO-certified data centres under EU / German law.

Hello World.

The site speaks for the software, so I won't. That part is finished — go look.

This is just a short personal note.

I've loved computers since before it was reasonable to, and somewhere along the way it stopped being a phase. In that time I've watched a lot of software get built, and most of it fail, so I'll be careful about what I claim here. An unlikely mix of people built this together, with the machines beside us, and it came out better than I expected. It shouldn't have held together. It did.

Everything in it was built against synthetic data — portfolios that never existed, returns no one ever earned. It works in that world. Now it has to work in yours. So we're talking to the people who actually move capital in institutional markets, asking for real data and real reasons it might break. Whether it works there is the only test that matters.

There's work ahead. We're not slowing down for it — if anything, we want to go faster. I'll write here when something is worth writing about, and not before.

— ProcessReengineer