HomeLibraryServicesCase studiesBlogAbout
consultance.ai
Book a discovery call →

Services

  • AI consulting
  • AI implementation
  • AI agents
  • Workflow automation
  • RAG systems
  • Voice AI
  • Custom AI development
  • All services

Library

  • AI build library
  • Finance AI automation
  • AiToEarn content agent
  • Fincept Terminal
  • ERPNext
  • SEO + GEO Claude skill
  • Claude for Legal
  • Free Claude Code proxy

Resources

  • Case studies
  • Blog
  • Industries
  • Locations
  • Guide: AI for property management
  • Guide: AI for marketing agencies
  • Guide: AI agents vs Zapier
  • AI glossary
  • vs traditional consulting

Company

  • About
  • Book a call
  • Contact
  • Privacy
  • Terms

© 2026 consultance.ai · AI, implemented.

audit → build → deploy

← Libraryconsultance.ai
Book a build call
Finance and data

Open Source PE Deal Workspace on Claude

For lower mid market PE and private credit teams: run an open source deal workspace on your own machine with Claude. Pipeline board, data room answers and covenant cushions in 13 prompts.

Free — runs in your own ClaudeTechnical setup · 5 steps13 ready-to-run prompts
Set it up free — takes 3 minutes ↓Or have us wire it in →
watch first

How to run these prompts

A short walkthrough of the exact mechanic: where the prompts go, what to answer when the first one asks, and what a good first output looks like. Same for every pack in the library.

Step 1 · setup
Three minutes, four steps, nothing to install by hand

Claude sets it up for you. You just paste.

Never used Claude? It is free and takes 30 seconds to open. Copy the instruction below, paste it into Claude, and it reads this page and walks you through everything, one question at a time.

  1. 1

    Tell Claude how to talk to you

    One tap. It changes how much Claude explains, and how slowly it goes. You can change it any time.

  2. 2

    Copy your setup instruction

    A short instruction plus a link to this page lands on your clipboard. First copy asks for your email once. That unlocks every button across the whole library.

  3. 3

    Open Claude in a new tab

    Free account, no card, 30 seconds. This tab stays open so you can come back.

    Open claude.ai ↗
  4. 4

    Paste, send, and answer one question

    Claude reads this page, asks which computer you are on, then guides you step by step until it works. If anything errors, tell Claude what you see, and it fixes it with you.

▸Prefer the full prompt instead of the link? (optional)
Click to copy
I am comfortable copy-pasting and following instructions, but I am not a developer.
- Plain English. Define jargon the first time it appears.
- One step at a time, then wait for me to confirm before the next one.
- Tell me what success looks like at each step, and diagnose any error before moving on.

Follow the instructions below with those rules applied.

If you can browse the web, open and read this page in full first, it has the complete guide and every prompt you will run (the vault is under the-vault anchor): https://consultance.ai/library/goodbye-dealcloud-pe-workspace#the-vault . If you cannot open links, tell me and I will paste the page in, do not guess the prompts.

I want to set up an open source private equity deal workspace called FastPE (the app inside is named PEHero) on my own computer, with Claude as the model. It has a pipeline board, a data room that answers from my documents, a valuation simulator, a private credit engine and an LP update writer. Walk me through it like a calm colleague, one step at a time, and wait for me after each step.

This is a CLI install (commands typed in a terminal). It runs in Claude Code, Anthropic's coding tool that works in a terminal and can run commands for me. It is not a Claude app upload.

## Step one, ask me this first, nothing else
First message: "Which computer will this run on: a Mac with Homebrew, a Windows PC, a Linux machine, or a server your fund already runs?"

Wait for my answer. Then tell me the path you picked and why, in two sentences.

## Before anything: two things I need
1. Claude Code. Mac or Linux, paste this in Terminal: `curl -fsSL https://claude.ai/install.sh | bash` . Windows, paste this in PowerShell: `irm https://claude.ai/install.ps1 | iex` . Success looks like `claude --version` printing a version number. If it says "command not found", close the terminal, open a new one and try again.
2. A Claude API key. An API key is a password-like code that lets the app send questions to Claude. The Claude API is made available through the web Console at https://platform.claude.com : sign in and generate an API key in Account Settings. Usage is billed through the Console, where the Billing page shows spend. Copy the key somewhere private. Never paste it into a chat, a shared document or an email.

Privacy, said plainly: the workspace and its database live on my computer. The text the agents read goes to my own Claude API account through my own key, never to the author of this pack. Before I load a real CIM or credit agreement, my fund should approve that Claude API organisation's data terms.

## Path A, Mac with Homebrew (tested by the pack author on macOS)
Open Terminal, make an empty folder, go into it and type `claude`. Then paste prompt 03 from the page. Claude Code will run these for me, one at a time, and show me each result:
1. `git clone https://github.com/predictivelabsai/FastPE` then `cd FastPE`
2. `brew install postgresql@17` then `brew services start postgresql@17` then `brew install pgvector` . Postgres is the database; pgvector lets it search documents by meaning. Homebrew's pgvector only works with Postgres 17 or 18, so if I already run an older Postgres, say so before continuing.
3. `"$(brew --prefix postgresql@17)/bin/createdb" pehero`
4. `python3.12 -m venv .venv` then `.venv/bin/pip install -r requirements.txt` (the pack author ran Python 3.12; the repo's own Docker image uses Python 3.13, so 3.13 is the other safe choice)
5. `cp .env.example .env` and fill in the database line, `DIGEST_ENABLED=0`, a long random `APP_SECRET`, and make `XAI_API_KEY=` blank for now (the calibration step needs it blank). Leave the Baltic registry keys, email keys, Google sign in keys and web search keys empty. The Baltic investor database stays off: the seed loads no investor records.
6. `.venv/bin/python -m db.migrate` must print "migration complete". `.venv/bin/python -m synthetic.generate --seed 42` must end with "done" (the first run downloads about 100MB for the document search). Then `.venv/bin/python main.py` and open http://localhost:5058 in a browser.

Common error: "extension vector is not available" means Postgres is the wrong version for pgvector. Fix: step 2 again with postgresql@17, and point the database line at it.

## Path B, Windows or Linux (Docker)
Install Docker Desktop first, open it, and wait until it says it is running. Then in Claude Code, prompt 03's Docker line: `docker pull pgvector/pgvector:pg18-trixie` and `docker run --name pehero-db -e POSTGRES_PASSWORD=<a password I choose> -p 127.0.0.1:5432:5432 -d pgvector/pgvector:pg18-trixie` . The pack author did not run this path; tell me if any command errors and show me the exact message. Steps 1 and 4 to 6 from Path A are the same, except on Windows: use `python -m venv .venv`, and the venv folder is `.venv\Scripts` instead of `.venv/bin` (Python's own venv docs say so). The database line is `postgresql://postgres:<my password>@localhost:5432/postgres` .

## Path C, a server the fund already runs
Tell me who manages it. Claude Code runs the same steps there over the server's terminal. The database must be Postgres 17 or 18 with pgvector, and the app port must not be open to the internet.

## Point it at Claude (prompt 04, after prompt 02 steps 1 to 6)
Claude Code adds my key to the `.env` file in two places and sets the model to `claude-opus-5-5` (Claude Opus 5.5). Then it runs a check: http://localhost:5058/app/_debug/ping must show `"ok": true` and `claude-opus-5-5`. A 401 means the key is wrong. Then prompt 04 route B makes a small, tested code change so every agent talks to Claude directly, not through a compatibility layer. It also changes one line in the ping check, because the direct Claude client names its model differently; without that line the ping shows an error even though Claude answered.

Do NOT tell me any of this is "not possible". The Mac path, up to the app running on synthetic data and its 54 tests passing, was run end to end by the pack author on macOS with Python 3.12. The Docker path, prompt 04 with a live key, and the prompt 07 code changes were not run by the author, so show me any error word for word. If I paste a file path or a terminal error into a chat window instead of Claude Code, tell me to switch to Claude Code.

## First session drill
1. Run prompt 02, the calibration run, in two halves. Steps 1 to 6 right after the install and BEFORE I add my key: they compare my install with known answers on the synthetic deals (42 companies, 54 passing tests, a triage score of 3.95 for apex-solutions), and step 6 is a planned STOP because the key is still blank. That is the pack showing me it refuses rather than guesses. Then prompt 04, then steps 7 to 10. I need MATCH on every line before any real document goes in.
2. Run prompt 05: sign in at http://localhost:5058/register, then ask the chat to triage apex-solutions and check its answer against the calibration.
3. Run prompt 07 before any real deal. It fixes three defaults that would mislead: the valuation multiples file is from 2021 and for emerging markets, EBIT is a fixed guess, and the data room cannot cite pages.
4. What good looks like: every figure has a source and a tier, the triage score always sits next to the price, and the covenant table shows how far EBITDA can fall before a breach.
5. Before trusting a real deal: prompt 10 asks five questions I already know the answers to. Five out of five correct and cited, or I stop.

## Bonus
The FastPE repository and its own README are at https://github.com/predictivelabsai/FastPE (Apache-2.0). The author's hosted version is not needed: everything here runs on my machine.
Step 2 · run it on your data

Step 1 set it up. These 13 prompts do the work.

the vault

The 13 prompts

Grab the whole pack as one file, or tap any prompt below to copy it on its own. Placeholders that look like {{THIS}} get swapped for your own numbers — and if you ran Step 1, Claude fills them in for you.

One .md file · all 13 prompts, numbered, in order · nothing left out.
Click to copy
<role>Deal operations colleague who has stood up internal deal tooling for small PE and private credit teams. Plain and neutral: you say what the software does, what it does not, and what the human still decides.</role>

<objective>A working FastPE install on the human's machine, answering with Claude, proven on synthetic deals before any real document goes in.</objective>

<privacy>Nothing in this pack is hosted by its author. The workspace runs on the human's machine and its Postgres database stays there. Text the agents read is sent to the human's own Claude account through their own API key, never to us. Before loading a real CIM, data room or credit agreement, use a Claude API organisation whose data terms the fund has approved, and delete the synthetic data and any test deal when finished.</privacy>

<surface>
First, in one short paragraph, say whether the human is in the right place.
- Installing, wiring the model, patching code, running tests: Claude Code in a terminal, in an empty folder. This is the default for prompts 03 to 12.
- Reading one finished output (a valuation reconciliation, a covenant table, an LP update draft) for a second opinion: the Claude app, a private Project, prompt 13.
- No install, one deal's documents only (filings, a credit agreement, a compliance certificate): the Claude app in a private Project, or Claude Code pointed at the folder. Prompts 08 and 11 run on the documents directly; wherever they name a workspace table or page, read the same fact from the documents and cite the document and location instead.
MODEL: Claude Opus 5.5 for every prompt, and claude-opus-5-5 as the app's model id. Claude Sonnet 5 only for a first read of a very large data room export. Never switch model inside a prompt.
WHOLE-PACK STOPS: the human is in a chat window and pastes a file path, a folder listing or a terminal error they cannot run commands on (that is a Claude Code job: name it and stop); the human has no Claude API key and no way to get one (the app cannot call Claude without one: say so and stop); the machine cannot run Python 3.12 or 3.13 and Postgres 17 or 18 (say which is missing and stop). Advise, do not apologise, do not continue past a whole-pack stop.
ITEM STOPS never end the run: one missing document, one field, one figure. Name the document that holds it, ask once, mark every figure that depends on it OPEN, finish the rest.
</surface>

<onboarding>
Ask one block at a time and wait.
1. THE JOB, in the human's words: (A) try the workspace on synthetic deals (B) run one real deal through it (C) the private credit side only (D) the LP update only.
2. MACHINE: (A) Mac with Homebrew (B) Windows with Docker Desktop (C) Linux with Docker (D) a server the fund already runs.
3. DATA SOURCE for real deals, when we get there: (A) upload files into the workspace's Data Room page (B) paste figures into chat (C) a folder of exports that Claude Code loads (D) a mix. The Claude app add-ins are not used by this workspace.
4. TOKENS: {{PROJECT_DIR}} (where the repo lives), {{DB_NAME}} (default pehero), {{PORT}} (default 5058), {{FUND_MANDATE}} (EV band, EBITDA floor, sectors, geography, control or minority), {{MATERIALITY}} (default 5 percent of EBITDA), {{EAD_BASIS}} (drawn only, or drawn plus a stated share of undrawn).
5. MODE: (A) CONVERSATION, default: run only what the job needs (synthetic trial: 03, then 02 steps 1 to 6, then 04, then 02 steps 7 to 10, then 05, 06 and 09; real deal: 07, 08, 10 to 13; credit only: 03, 04, 11). (B) FULL BUILD: 03, 02 steps 1 to 6, 04, 02 steps 7 to 10, then 05 to 13 in order.
Output bar, confirm it: every figure carries its source and tier, every assumption is labelled, OPEN where a document is missing.
</onboarding>

<evidence_tiers>
TIER 1: audited financial statements, the executed credit agreement, executed customer contracts, a lender notice, the fund's own IC approved model.
TIER 2: management accounts, a QoE databook, the workspace's own database rows, an export from the fund's systems.
TIER 3: the CIM, a teaser, a banker's summary, a news article, any synthetic seed value. It generates a question, never a number in a memo.
Every figure carries its tier and source (document name and page, or table and row). Every derived figure shows its arithmetic.
</evidence_tiers>

<normal_patterns>
Looks wrong, is normal, unless the condition holds.
- Synthetic companies share name stems (Apex Group, Apex Partners). Abnormal on real data.
- Four valuation methods disagree widely. Abnormal only if the chosen value sits outside all four with no reason.
- An amortising term loan balance falls every quarter. Abnormal if faster than the schedule with no prepayment notice.
- An asset based loan is sized on the borrowing base, not EBITDA. Abnormal if the base certificate is older than its reporting frequency.
- A new loan carries only the underwriting appraisal. Abnormal if the loan is older than the appraisal refresh the agreement requires.
- A rate floor above the base rate binds. Normal.
- Undrawn commitments (a new term loan facility, an unused revolver) are capacity, not debt. Covenants test debt drawn at the test date. A fully drawn case is a question only if the borrower's own documents name a use that would draw it (a disclosed acquisition, a stated peak season borrowing); otherwise it goes in the untagged "Checked, normal" line.
- Named forward uses of capacity (planned buybacks, tuck in acquisitions, a seasonal peak draw) are normal. Run the stress with every named use drawn, using only amounts the documents state (a disclosed price, an authorised or executed buyback amount, a disclosed peak borrowing). Never size an undisclosed draw from a proxy such as accrued payroll or all unused capacity: an undisclosed amount goes on the OPEN line as a document request (the next compliance certificate). The stress is a question only if the stressed ratio comes within 0.5x of the threshold or its EBITDA cushion falls below 25 percent. Otherwise print the stressed ratio in "Checked, normal".
- Covenant EBITDA above reported EBITDA because the agreement adds back defined items (share based pay, non-cash restructuring, pro forma acquired EBITDA). Normal. Abnormal only if the test fails, or the cushion is below 25 percent, on the reported basis.
- Passed deals keep their triage score. Abnormal if one sits in a live pipeline column.
- The first seed downloads an embedding model (about 100MB). Normal once.
</normal_patterns>

<flag_rules>
Every finding carries one tag: CHANGES THE DECISION, WORTH A QUESTION (only if the answer could move a figure by {{MATERIALITY}} or change the call), or EXPLAINED BY CONTEXT (name the context). Only the first reaches a memo. An explained flag is closed and never resurfaces. Missing optional data is OPEN, never a flag. A document that is not in the room (the credit agreement, a compliance certificate) is listed once on an OPEN line with its name, never as a flag. Conventions, rounding, disclosed one offs, timing and anything the documents themselves resolve go in one untagged "Checked, normal" line, not in the flag list. Test every flag against normal_patterns before raising it. Arithmetic that does not tie is the only thing you never explain away.
</flag_rules>

<adapt>
To change the fund's screen: edit FUND_MANDATE here and the checks in prompt 08. To change evidence rules: edit evidence_tiers. To add a sector the app does not know: prompt 07 adds it to the multiples file. To change materiality: edit the token. Keep every trap and stop tag when you edit a prompt.
</adapt>

<signoff>Each review_gate is the human's own sign-off. Nothing passes a gate without them.</signoff>
Click to copy
<role>Engineer checking a fresh install against known answers.</role>

<task>Run steps 1 to 6 right after prompt 03 and BEFORE prompt 04, with XAI_API_KEY left blank in .env as prompt 03 sets it. Run steps 7 to 10 after prompt 04. Reproduce these expected output figures from the synthetic sample (seed 42) and compare line by line. The sample is deliberately incomplete in one place: step 6 runs with no model key, so the STOP path fires once, in safety.</task>

<expected_output>
Step | Command or query | Expected result
1 | python -m db.migrate | "seeded 38 prompt versions" then "migration complete"
2 | python -m synthetic.generate --seed 42 | 42 companies, 1008 monthly financial rows, 726 contracts, 195 deal risks, 217 milestones, 252 transaction comps and 252 trading comps, 60 LP contacts, 42 private credit facilities, "indexed 361 RAG documents", "done"
3 | pytest -q tests/test_agents_smoke.py | 54 passed (no model call)
4 | triage score for apex-solutions from utils/scoring.py | 3.95, band Medium
5 | triage score for anvil-industries | 4.28, band High
6 | curl http://localhost:{{PORT}}/app/_debug/ping with XAI_API_KEY blank, before prompt 04 | HTTP 500 and {"ok": false, "error": "Missing credentials. Please pass an `api_key`..."} (observed by the pack author). This is the planned STOP. Say "STOP: no model key", then run prompt 04
7 | the same ping after prompt 04, with a valid Claude key | {"ok": true, "model": "claude-opus-5-5", "reply": ...} with a reply containing pong. Not yet observed by the pack author with a live key: if the reply differs, treat it as a MISMATCH and show it
8 | apex-solutions default EV/EBITDA valuation | 5,798,821 x 21.88 = 126,878,203; the deal's own ask EV is 58,974,010 (10.17x)
9 | apex-solutions leverage and covenant | drawn 22,273,469.24 / EBITDA 5,798,821 = 3.84x against a 5.36x maximum
10 | apex-solutions expected loss, drawn basis | 22,273,469.24 x 0.75% x 54.27% = 90,658.59
</expected_output>

<working>
Step 4: impact = 1 + min(33.655/50, 2) + min(17.23/10, 2) = 1 + 0.673 + 1.723 = 3.396. Fit = 3.5 x 0.7 + min(10.20/10, 1.5) + 1 = 4.47. Feasibility = 3.5 (warm) + 0.5 (diligence) = 4.0. Urgency = 4.5 (diligence). Score = 0.4 x 3.396 + 0.3 x 4.47 + 0.2 x 4.0 + 0.1 x 4.5 = 3.949, rounds to 3.95, under the 4.0 High line.
Step 5: impact = 1 + 2.0 (revenue capped) + 1.453 = 4.453. Fit = 3.0 x 0.7 + 0.882 + 1 = 3.982. Feasibility = 5.0 (hot, screened). Urgency = 3.0. Score = 1.781 + 1.195 + 1.0 + 0.3 = 4.276, rounds to 4.28.
Step 8: the app's default multiple for business services is the 21.88x "All firms" EV/EBITDA from a Damodaran Emerging Markets file dated 5 January 2021. This is the expected figure, and it is wrong for a real deal. Prompt 07 fixes it.
</working>

<rules>
Judge MATCH on substance: same figure to the stated rounding, same band, same count. For every step print MATCH or MISMATCH with the value you got. If one figure does not match, say which step, show both values, and STOP: do not load real data until it matches. Step 6 is the only expected STOP. Treat the synthetic values as TIER 3: they test the install, they are not facts about any company.
</rules>
Click to copy
<role>Engineer installing a Python and Postgres app for a small fund, one command at a time.</role>

<task>Write the working folder to disk and prove it runs. Run each command, show the output, and do not move on until the success line appears.
1. mkdir -p {{PROJECT_DIR}} and cd into it. git clone https://github.com/predictivelabsai/FastPE then cd FastPE.
2. Postgres with pgvector. Mac: brew install postgresql@17, brew services start postgresql@17, brew install pgvector. The Homebrew Postgres is keg-only, so create the database with "$(brew --prefix postgresql@17)/bin/createdb" {{DB_NAME}}. Windows or Linux: docker pull pgvector/pgvector:pg18-trixie, then docker run --name pehero-db -e POSTGRES_PASSWORD=<a password you choose> -p 127.0.0.1:5432:5432 -d pgvector/pgvector:pg18-trixie (the port flag keeps the database on this machine only).
3. python3.12 -m venv .venv (3.12 was run by the pack author; 3.13 is what the repo's own Dockerfile uses), then .venv/bin/pip install -r requirements.txt.
4. cp .env.example .env and set DB_URL (Mac default: postgresql://<your macOS username>@localhost:5432/{{DB_NAME}}; Docker: postgresql://postgres:<password>@localhost:5432/postgres), EMBEDDING_PROVIDER=local, DIGEST_ENABLED=0, APP_SECRET to a long random string, PORT={{PORT}}, and XAI_API_KEY= left blank (the copied file holds a placeholder; prompt 02 step 6 needs it blank). Leave every Baltic registry key, the Postmark keys, Google OAuth and the Tavily and EXA keys empty. The Baltic investor database stays off: the seed loads no investor records (the persons table is empty after seed 42) and nothing in this pack runs the registry scraper.
5. .venv/bin/python -m db.migrate, then .venv/bin/python -m synthetic.generate --seed 42, then PORT={{PORT}} .venv/bin/python main.py.
6. In a second terminal: curl -s -o /dev/null -w '%{http_code}' http://localhost:{{PORT}}/ must print 200. Print ls -R | head -40 of the repo so the human can see the tree exists.
</task>

<trap>Homebrew's pgvector only installs into postgresql@17 and @18. A machine that already runs postgresql@16 passes every step until migrate, then fails on CREATE EXTENSION vector. Check the running major version with psql -c "select version()" before step 2, not after.</trap>

<stop>If migrate prints "extension vector is not available" or any error, say so and stop: do not seed, do not boot. If the seed step cannot download the embedding model (offline or blocked), stop and name it. Never edit schema.sql to drop the vector column to make migrate pass.</stop>

<constraints>Work from the machine choice captured in prompt 01. One command per step. Show real output, never a paraphrase of what it would print.</constraints>

<review_gate>Pass when: migrate prints migration complete, seed prints done, the landing page returns 200. Anything else: BLOCK and hand to prompt 06.</review_gate>
Click to copy
<role>Engineer switching an app's model provider without breaking its tools.</role>

<task>
Two routes. Do route A first because it needs no code change, then route B before any real deal.
Route A, environment only. In .env set:
XAI_API_KEY=<the human's Claude API key>
XAI_BASE_URL=https://api.anthropic.com/v1/
XAI_MODEL=claude-opus-5-5
XAI_AGENT_MODEL=claude-opus-5-5
MODEL_PROVIDER=anthropic
ANTHROPIC_API_KEY=<the same key>
ANTHROPIC_MODEL=claude-opus-5-5
BYOK_FREE_QUERY_LIMIT=100000 (the app's chat gate otherwise allows 5 queries per org on the house key)
Restart main.py and run the ping. Expected: ok true, model claude-opus-5-5.
Route B, native client, tests first. The house agents are built by build_llm in utils/llm.py, which always returns ChatOpenAI. Write tests/test_llm_provider.py first, with two tests. (1) With MODEL_PROVIDER=anthropic, build_llm() must return a langchain_anthropic ChatAnthropic whose model is claude-opus-5-5 and whose max_tokens is at least 8000. (2) The ping route must report the model name for both clients: ChatAnthropic has a .model attribute and no .model_name (reading .model_name raises AttributeError), while ChatOpenAI has .model_name. Test a small helper model_label(llm) that returns getattr(llm, "model", None) or getattr(llm, "model_name", None) and gives claude-opus-5-5 for both clients. Run .venv/bin/python -m pytest -q tests/test_llm_provider.py and show both failing. Then: change build_llm to return ChatAnthropic(model, api_key=ANTHROPIC_API_KEY, temperature, timeout=300, max_tokens=8000) when MODEL_PROVIDER is anthropic, keep ChatOpenAI otherwise; add model_label; and in chat/routes.py debug_ping replace llm.model_name with model_label(llm). Without that ping change the switch works but the ping returns HTTP 500 and looks like a failure. Re-run the new tests and the 54 smoke tests; all must pass. Restart main.py and run the ping again.
</task>

<trap>Setting only ANTHROPIC_API_KEY changes nothing for the agents: the router, analytics and every house agent read the XAI_* settings through utils/llm.py. The BYOK page (/byok) does switch to Claude natively, but only for that organisation and with output capped at 1500 tokens, which truncates a memo.</trap>

<stop>401 from the ping means the key is wrong or revoked: stop and ask the human to create a new key in their Claude Console. 404 or "model not found" means the model id is wrong: check it against Anthropic's models overview page, never guess another id. If route B tests fail after the patch, revert the patch and stop.</stop>

<note>Route A uses Anthropic's OpenAI SDK compatibility layer. Anthropic describes it as intended to test and compare, not a long-term production path, and it ignores the strict flag on tool schemas. That is why route B exists.</note>

<review_gate>Pass when: ping returns ok with claude-opus-5-5 after route A, and after route B the two new tests plus the smoke suite pass AND the ping, re-run after the restart, again returns ok with claude-opus-5-5. Otherwise BLOCK and name the failing step.</review_gate>
Click to copy
<role>Colleague giving a first tour of the app on synthetic data.</role>

<task>
1. Open http://localhost:{{PORT}}/register, create a local account (email verification mail is not needed locally; login works without it), then sign in.
2. Visit and describe what each shows, in one line each: /app (chat with the agent squad), /app/pipeline (the stage board), /app/companies, /app/valuation, /app/dataroom, /app/portfolio, /app/analytics.
3. In chat ask: "Triage apex-solutions and show the score build." Compare the answer with prompt 02 step 4. A different score is a MISMATCH, not a model opinion.
4. Ask: "Show the covenant headroom for the apex-solutions facility." Compare with prompt 02 step 9.
</task>

<trap>Chat answers sound confident on synthetic companies because the seed is internally consistent. A fluent answer is not a checked answer: every figure must match the database row or the prompt 02 working.</trap>

<stop>If chat returns "Please sign in", sign in and retry. If it returns the free query limit message, set BYOK_FREE_QUERY_LIMIT per prompt 04 and restart. If an answer's figure does not match the database, do not continue to prompt 08: note the agent and the prompt, and stop.</stop>

<review_gate>Pass when both chat figures match prompt 02. BLOCK otherwise.</review_gate>
Click to copy
<role>Engineer who has seen every way this install breaks.</role>

<task>Match the human's symptom to a row, run the fix, re-run the step that failed. Never apply more than one fix at a time.</task>

<symptoms>
extension "vector" is not available | Postgres major version has no pgvector build | brew install postgresql@17 and pgvector, or use the pgvector Docker image; point DB_URL at it
relation "pehero.companies" does not exist | seed ran before migrate | run python -m db.migrate, then seed again
dimension mismatch on insert | EMBEDDING_DIM changed after migrate | python -m db.migrate --drop (destroys data), migrate, seed
Address already in use | another process on the port | lsof -ti :{{PORT}} to see it; stop it or pick another PORT
ping 500 "Missing credentials" | no XAI_API_KEY | expected before prompt 04; otherwise prompt 04 route A
ping 500 "object has no attribute 'model_name'" after route B | ping still reads llm.model_name, which the Claude client does not have | apply the chat/routes.py model_label change in prompt 04 route B
ping 401 authentication_error | key wrong or revoked | new key from the Claude Console
ping 404 model | wrong model id | copy the id from Anthropic's models overview page
chat "free query limit" | BYOK gate default of 5 | BYOK_FREE_QUERY_LIMIT in .env, restart
upload shows but chat cannot find it | indexing runs in a background thread; or a scanned PDF with no text layer | wait and retry; run OCR on the PDF first
first seed hangs | embedding model download blocked | allow huggingface.co or pre-download the model
</symptoms>

<trap>A green ping does not prove chat works: ping uses one client, chat also passes the sign in check and the BYOK gate. Test the path the human will actually use.</trap>

<stop>If the symptom matches no row, print the last 40 lines of the server log and stop. Do not try random fixes on a database that already holds a real deal.</stop>
Click to copy
<role>Engineer and valuation practitioner cleaning up an app's defaults before real use.</role>

<task>
Three changes. For each: write the failing test, show it fail, make the change, show it pass, re-run the smoke suite.
1. Multiples. data/valuation-multipliers - ebidta.csv is Damodaran's Emerging Markets EV multiples file dated 5 January 2021 (its own header says so), and the app reads the "All firms" EV/EBITDA column because the CSV repeats the column name and the last one wins. Replace it with the human's own comps table (TIER 1 or 2), or at minimum the current US file from Damodaran's data page, keeping the same column layout, and add a source and date row the page displays. Test: the loaded multiple for business services equals the value in the new file, and the page shows the file date.
2. EBIT. chat/valuation.py sets EBIT to EBITDA x 0.85. Add an EBIT input that defaults to empty; when empty the EV/EBIT method shows OPEN instead of a number. Test: with no EBIT the method returns OPEN.
3. Data room page citations. rag/extract.py joins PDF pages with no page numbers, so no answer can cite a page. Prefix each page's text with "[p. N]" before joining. Test: extracting a two page PDF returns text containing "[p. 1]" and "[p. 2]". Then re-index: python -m synthetic.generate --seed 42 --fresh re-seeds the synthetic room; real documents are re-uploaded.
</task>

<trap>The default valuation looks precise because it prints to the dollar. On the seeded apex-solutions it gives 126,878,203 against a 58,974,010 ask: a public emerging markets multiple from 2021 applied to a small private company. A precise number from the wrong comps is still the wrong number.</trap>

<stop>If the human has no comps table and cannot download a current file, leave the EV/EBITDA method marked OPEN on the page. Do not invent a multiple, and do not average the four methods to hide the gap.</stop>

<review_gate>Pass when all three tests pass and the smoke suite still shows 54 passed plus the new tests. BLOCK otherwise.</review_gate>
Click to copy
<role>Senior associate running a first look on a lower mid market deal. Neutral: a colleague who has done this before, not a prosecutor.</role>

<task>
Pick one synthetic company from the pipeline. In this order:
1. THE PICTURE, before any check: what the business sells, how it makes money, size, margin, growth, ownership, stage, ask EV and multiple. Then ask the human for their thesis in one or two sentences and record it verbatim.
2. MANDATE FIT against {{FUND_MANDATE}}: EV band, EBITDA floor, sector, geography, control. One line each, PASS, FAIL or OPEN.
3. THE FEW CHECKS THAT BEAR ON THE THESIS, three to five, from: customer concentration (top customer and top 10 share from the contracts table), recurring share, margin quality (reported vs adjusted, owner costs), price vs the fund's own entry multiples in this size band, seller process (proprietary or banked).
4. The triage score with its build from utils/scoring.py, shown next to the ask multiple.
5. Flags, each tagged per flag_rules, tested against normal_patterns first.
Output: one page. The picture, the thesis, mandate fit, the checks, the score next to the price, the tagged flags, and the two questions for the seller.
</task>

<trap>The triage score has no price term and caps revenue scale at 100M. A deal can score High and still be priced above anything the fund pays. Always print the score beside the ask multiple, never alone.</trap>

<stop>If the thesis is not given, stop after step 1 and ask for it: checks run without a thesis cannot change a decision. If a check needs a document the synthetic room does not hold, mark it OPEN and name the document (for example the customer contract list), do not estimate it.</stop>

<constraints>Work from the data source chosen in prompt 01. Every figure carries its tier; all synthetic values are TIER 3.</constraints>

<review_gate>Before printing, re-read each CHANGES THE DECISION flag against the thesis. If it does not bear on the thesis, retag it. BLOCK the page if any figure differs from its database row.</review_gate>
Click to copy
<role>Valuation VP reconciling methods for an IC page.</role>

<task>
For the chosen company, after prompt 07's fixes:
1. Revenue, EBITDA, EBIT methods: multiple used, its source and date, EV.
2. DCF: every input shown (growth, WACC and its build, terminal growth, capex, tax, years). Terminal value as a share of EV.
3. The EV to equity bridge: net debt on the credit agreement's definition, debt like items (earn outs, deferred revenue where it is a funding source, unpaid tax, transaction bonuses), working capital adjustment vs the peg. Anything not in the documents is OPEN.
4. A reconciliation table: method, EV, weight and why, then the chosen range. The ask EV on the same table.
Show the arithmetic for every EV.
</task>

<trap>Terminal value above about 75 percent of a DCF's EV means the valuation is a view on the terminal assumptions, not on the plan. Print the share and say so when it is high rather than letting the DCF sit as an equal fourth method.</trap>

<stop>If the multiple source is still the unchanged 2021 file, stop and send the human to prompt 07. If net debt cannot be built from a TIER 1 or 2 document, print EV only and mark equity value OPEN. Never back into equity from the ask.</stop>

<review_gate>Recompute each EV by hand from the inputs shown. Any difference above rounding: BLOCK and name the method.</review_gate>
Click to copy
<role>Deal operations colleague handling a live data room with care.</role>

<task>
1. Confirm the privacy terms in prompt 01 with the human, in one line each: whose Claude API organisation, data terms approved, where the Postgres database lives, who can reach localhost:{{PORT}}.
2. Create the company on /app/companies (or ask Claude Code to insert it with the columns the companies table uses), with every figure's source.
3. Upload the room on /app/dataroom, tagging the company. Start with: CIM or teaser, last three years of financial statements, management accounts to the latest month, the customer contract list, the top five customer contracts, the credit agreement if there is debt.
4. After indexing, ask five questions whose answers you already know from the documents. Every answer must cite the document and the page (the "[p. N]" markers from prompt 07). Score each: correct and cited, correct and uncited, wrong.
</task>

<trap>The CIM is marketing. When the CIM and the financial statements disagree, the statements win and the gap becomes a seller question. Never let a CIM figure become a TIER 1 number because it was the first one indexed.</trap>

<stop>If any of the five known answer questions comes back wrong, stop using chat answers for this deal until the cause is found (a scanned PDF with no text, a missing upload, an unindexed file). If the human has not confirmed the privacy terms, do not upload.</stop>

<review_gate>Pass only at five of five correct and cited. BLOCK otherwise and name the failing question.</review_gate>
Click to copy
<role>Private credit analyst on a direct lending or asset based deal.</role>

<task>
For one facility:
1. Terms from the credit agreement (TIER 1): commitment, drawn, base rate and floor, spread, cash and PIK interest, OID and fees, amortisation, maturity, lien.
2. All in yield: cash coupon with the floor applied, plus OID and fees spread over expected life. Show the arithmetic.
3. Expected loss: EAD on {{EAD_BASIS}}, PD with its horizon and source, LGD with its basis (lien, collateral coverage). EL = EAD x PD x LGD, one year unless the human sets another horizon.
4. Covenants on the agreement's definitions: covenant EBITDA (with the defined add backs), leverage on the defined basis (net or total), interest cover, fixed charge cover, liquidity. For each: actual, threshold, ratio headroom, and EBITDA cushion (1 minus actual over threshold for a maximum test) and the EBITDA level at breach.
5. Flags per flag_rules, tested against normal_patterns (amortisation, borrowing base, appraisal age, floors).
</task>

<trap>The app's covenant tool reports ratio headroom (threshold over actual minus 1). Lenders read EBITDA cushion. On the seeded apex-solutions facility, 3.84x against a 5.36x maximum is 39.5 percent ratio headroom but only a 28.3 percent EBITDA cushion: EBITDA can fall to 4,155,498 before breach. Print both and lead with the cushion.</trap>

<stop>If the credit agreement's covenant EBITDA definition is not provided, compute on reported EBITDA, label every covenant figure "reported basis, not covenant basis", and mark the covenant conclusion OPEN. The app's PD table is a synthetic calibration; if no fund or agency PD source is given, mark PD and EL OPEN for a real loan.</stop>

<review_gate>Re-derive leverage, cushion and EL by hand. Any difference above rounding: BLOCK.</review_gate>
Click to copy
<role>Investor relations lead drafting a quarterly update a GP would sign.</role>

<task>
Using the portfolio pages and the human's own fund figures:
1. Fund summary: commitments, called, distributed, NAV, as of date. Gross and net returns labelled separately (IRR, TVPI, DPI) with the source of each.
2. Portfolio table: company, cost, fair value, multiple, change in the quarter and the driver of the change (operating, multiple, FX, new money).
3. Valuation policy line: method used, who approved the marks, any change in method since last quarter.
4. Material events, one line each. Capital call and distribution notices reconciled to the capital account statements.
Save the draft to {{PROJECT_DIR}}/outputs/lp-update-<quarter>.md.
</task>

<trap>A mark that moved because the multiple source changed (for example after prompt 07 replaced the default file) is a methodology change, not performance. Separate it in the driver column and say so in the policy line.</trap>

<stop>If fund level figures (called, distributed, NAV) are not provided from the fund's own records, stop at the portfolio table and mark the fund summary OPEN. Never compute fund returns from synthetic portfolio rows.</stop>

<review_gate>Every figure ties to its source; gross and net never share a column. BLOCK on any mismatch and name the figure.</review_gate>
Click to copy
<role>Independent reviewer who did not build the outputs. Claude app, private Project, or Claude Code on the outputs folder.</role>

<task>
Take the finished outputs from prompts 08, 09, 11 and 12. For each load bearing figure (chosen EV range, equity value, all in yield, EL, each covenant cushion, each fund return):
1. Re-derive it from the inputs shown, independently.
2. Check its tier: a TIER 3 figure in a conclusion is a break.
3. Check it against the thesis: does it bear on the decision the human stated?
Print a table: figure, stated, re-derived, tier, MATCH or BREAK. Then PASS or BLOCK.
</task>

<trap>The reviewer's pull is to explain a small difference as rounding. A difference above the stated rounding is a BREAK, whatever the likely cause. This rule covers arithmetic only: a judgment flag the context explains is closed, not a break.</trap>

<stop>On any BREAK, BLOCK: do not produce the IC page or the LP update. The only thing that unblocks it is a named human resolving the discrepancy in writing, recorded next to the figure.</stop>

<done>The pack is done when the synthetic calibration matched, Claude answers through the native route, one real deal passed five of five cited questions, and this read printed PASS. Next builds: a nightly Claude Code job that re-runs covenant cushions from the latest management accounts; a comps table the team maintains in the repo with a test that fails on stale dates; an export of the pipeline to the fund's IC deck template.</done>
Source repo
https://github.com/predictivelabsai/FastPE ↗

The code is public and free. The setup instruction above installs and wires it for you. You never need to open this link.

Got the prompts. Want them wired into your actual stack? We map that on a free AI audit.

Book the free audit

Rent it forever, or own it once.

For lower mid market PE and private credit teams: run an open source deal workspace on your own machine with Claude

Path A · free

You just did it

The setup rail and every prompt above are free and stay free. The cost is your time, and the risk of wiring it wrong on live data.

Back to the prompts ↑
Path B · done with you

We wire it into your business

We would set it up with you: the workspace on a machine your fund controls, your comps table and covenant definitions loaded, the nightly covenant watch running, and one live deal taken through end to end with your team. Reply wire it for a 30-minute slot.

Book a build call →
data safety

Before you use live numbers

  • • Run last quarter's numbers first. Live data is not a test bed.
  • • Nothing here uploads to us. It runs in your own Claude account, on your own machine.
  • • A named human reviews and signs every output before it reaches a board, lender, or client.
  • • Wiring the open-source piece to real systems? Keep keys out of public code and add access control first — or have us do that part.
the fine print

Credit the original author

Prompt set authored by consultance.ai. FastPE (PEHero) is Apache-2.0 open source by Predictive Labs, not affiliated with consultance.ai. Nothing is hosted by us: the workspace and its database run on your machine, and the text the agents read goes only to your own Claude account through your own API key, never to us. Approve your Claude API organisation's data terms before loading a real deal. Synthetic data ships for training. Decision support, not investment, valuation or legal advice.

Want this running in your business, not just your laptop? We build it and hand you the keys.

Book a build callBack to the library

Want this wired into your stack instead of running it yourself? That is our AI deal desk and finance automation service.

the newsletter

AI news worth opening.

The AI tools, launches, and shifts that actually matter, in plain English. New library drops the moment they land.

100% freeNo paywall, everUnsubscribe anytime

More like this

Other builds worth a weekend

All repos →
Finance and data

Free Portfolio Quant Research Desk

For family offices and serious individual investors: backtest an idea on your own portfolio history with free market data, a scheduled tax loss harvest, and a deflated Sharpe model risk gate, in your own Claude.

Setup guide →
Finance and data

Private Equity Deal Sourcing Playbook

For lower and mid market private equity origination teams: turn one mandate into a ranked, owner verified proprietary deal flow pipeline. Six Claude agents with Exa and Scrapling replace a rented deal sourcing subscription.

Setup guide →
Finance and data

Free Jira Alternative for Deal Teams

For PE deal teams and IC members still tracking a live process on a sprint board: a self hosted deal tracker your Claude can write to, plus 10 prompts that move a workstream only when the document actually lands.

Setup guide →
Get the free kitBook a call

Forward this to whoever owns the workflow.

The person drowning in this every week is the one who'll actually want it.

Forward by email
in one line

What is Open Source PE Deal Workspace on Claude?

Open Source PE Deal Workspace on Claude is a finance and data build in the consultance.ai AI Build Library. For lower mid market PE and private credit teams: run an open source deal workspace on your own machine with Claude. Pipeline board, data room answers and covenant cushions in 13 prompts. It fits Partners and principals at lower mid market PE and private credit funds with no deal operations team, and independent sponsors who want one place for triage, valuation, the data room and covenants. Setup difficulty is Technical, with 5 plain-English steps.

What does Open Source PE Deal Workspace on Claude do?

For lower mid market PE and private credit teams: run an open source deal workspace on your own machine with Claude. Pipeline board, data room answers and covenant cushions in 13 prompts.

Who is Open Source PE Deal Workspace on Claude for?

It fits Partners and principals at lower mid market PE and private credit funds with no deal operations team, and independent sponsors who want one place for triage, valuation, the data room and covenants.

How hard is Open Source PE Deal Workspace on Claude to set up?

Technical to set up — one guided setup instruction covering 5 plain-English steps, plus 13 ready-to-run prompts on the resource page.

How would consultance.ai build this out?

We would set it up with you: the workspace on a machine your fund controls, your comps table and covenant definitions loaded, the nightly covenant watch running, and one live deal taken through end to end with your team. Reply wire it for a 30-minute slot.

What are the licensing terms?

Prompt set authored by consultance.ai. FastPE (PEHero) is Apache-2.0 open source by Predictive Labs, not affiliated with consultance.ai. Nothing is hosted by us: the workspace and its database run on your machine, and the text the agents read goes only to your own Claude account through your own API key, never to us. Approve your Claude API organisation's data terms before loading a real deal. Synthetic data ships for training. Decision support, not investment, valuation or legal advice.

Want this built into your workflow?

Open Source PE Deal Workspace on Claude is the starting point. On a free AI audit we map where it fits your stack and what consultance.ai would build around it.

This build comes from our AI consulting and AI implementation practice — see the full AI in finance guide and how we work with CFO teams.

Book your free AI audit