Interview Prototype · Solo buildv0.1

Cap Table Reconciler

A small system for surfacing the gaps a private-markets analyst would otherwise find by hand — before any judgment work begins.

Why this exists

Built solo over a week ahead of a private-markets interview. The goal was to demonstrate how I'd approach the role's actual mechanics — gap-detection on real-world cap-table messiness, with a deliberate hands-off posture on valuation — in code rather than in conversation. Not a product, not in production use, not affiliated with any company.

Flask · HTMX · openpyxl · pdfplumber · Prepared May 2026

Built by Subhankar Shukla. Independent project — not affiliated with, endorsed by, or representative of any company. All cap-table data shown is fictional.

The problem

Cap tables arrive messy. The judgment work can't begin until the data is clean.

A private-markets analyst working a cap table for diligence, valuation, or a secondary transaction will almost never get a workbook they can model from directly. The data arrives with mixed date formats, subtotal rows interleaved in the data range, a SAFE sitting on a separate tab past its conversion trigger, a vendor warrant referenced only in a side letter, and an anti-dilution variant cell that someone left blank because they meant to ask counsel.

None of these are judgment problems. They are data-hygiene problems that happen to sit upstream of the judgment work. The question this project tries to answer is simple: can the hygiene step be done by a system, in a way that's honest, auditable, and explicit about what it refuses to decide — leaving the analyst to do the analysis?

How it works

A messy workbook becomes a clean handoff in five steps.

The system is small on purpose. Two of the five steps are pure engineering, two are human, and the analyst is in the loop on every judgment call. There is no model deciding what counts as a gap, and no model picking the resolution.

  1. 01
    Input

    A messy cap-table workbook goes in.

    Real-world cap tables arrive as Excel files with mixed date formats, subtotal rows interleaved in the data range, an unconverted SAFE sitting on a separate tab, and a vendor warrant referenced only in a side letter. The only input to the system is a single .xlsx. Nothing scraped, nothing connected to a data provider.

  2. 02
    Engineering

    A purpose-built parser normalizes what it can.

    The parser scans the first dozen rows to locate the header (handling title rows and prepended blanks), skips subtotal rows by name pattern, normalizes most common date formats to ISO, and reads convertibles and side-letter tabs when the tab names match a whitelist. Where the file is too far from the expected shape — holder-level rows with duplicate class names, non-standard tab names, prose in numeric cells — the parser degrades to a structured warning report rather than fabricate a clean ingest. The analyst sees what got dropped and why.

  3. 03
    Engineering

    A human-written checklist surfaces gaps.

    Once parsed, the data is run against a checklist authored by hand — anti-dilution variants, SAFE conversion triggers, stale option pools, off-table warrants, side-letter ambiguities, participating-cap multiples. Each finding cites the exact field path it came from. There is no model deciding what counts as a gap.

  4. 04
    Analyst

    The analyst resolves each finding; the system recomputes.

    Findings with a deterministic resolution shape — SAFE conversion share count, anti-dilution variant picker, warrant fully-diluted inclusion toggle, side-letter scope adjudication, stale-pool date refresh — have inline forms. Others surface for analyst action without a built-in form. After any resolution, the cap table updates in memory, the waterfall recomputes, the findings list re-runs. The judgment stays with the analyst; the math stays with the system.

  5. 05
    Output

    A clean handoff bundle gets exported.

    One click produces a structured JSON, a static .xlsx with cap-table / convertibles / side-letters / breakpoints / findings tabs, a live-formula workbook for what-if scenarios, and a markdown audit-memo skeleton with explicit ANALYST placeholders for judgment sections. Everything is a plain file — diff-able, version-control-friendly, no proprietary format.

Step 03 in detail · The checklist

Eight categories of gap the checklist is told to look for.

The checklist is the only place a human authored strategic logic. It runs against the parsed cap table and decides what counts as a finding. Each rule was written by hand against a specific kind of real-world cap-table mess. Change the list, and a different checklist runs against the same parsed structure. Parser-level handling — subtotal rows, date normalization, seniority detection — sits one layer below this and is described in step 02 above.

  • 01

    Anti-dilution variant

    Flag preferred classes where the variant cell is blank — broad-based vs full-ratchet materially changes share count under any future down round.

  • 02

    Full-ratchet documentation

    Preferred classes carrying a full-ratchet variant where the triggering threshold or carve-outs aren't recorded. Asks for the charter cite, doesn't infer it.

  • 03

    Unconverted SAFE

    Detect SAFEs whose conversion trigger has been met but whose resulting shares never made it onto the cap table tab.

  • 04

    Stale option pool

    Last grant date precedes the most recent funding round — usually means pre-round 409A FMV grants and an unrefreshed pool size.

  • 05

    Off-table warrant

    Vendor or strategic warrants referenced in side letters or the convertibles tab but not represented as fully-diluted shares.

  • 06

    Side-letter scope unresolved

    Side letters with open Q-prefixed lines (MFN scope undefined, redemption-right enforceability TBC, pro-rata termination unspecified). Surfaced for in-session adjudication; not auto-resolved.

  • 07

    Participating cap undefined

    Participating-preferred classes missing a cap multiple — the cap-reach breakpoint can't be computed, so the waterfall under-reports preferred upside.

  • 08

    Dual-class voting differential

    Common stock with founder-favourable voting multipliers (10x, super-voting) referenced in the charter but absent from the cap-table file.

See it in action

A short walkthrough of the live system.

~80 seconds, no audio. The video below tours the live tool — home page, the messy Pelaut Logistics fixture, the waterfall page, a live sensitivity-slider edit, and the export step. The guide beneath tells you what to look for at each beat.

Walkthrough · 80 seconds · local Flask app
~80 seconds, no audio. Home → messy fixture (Pelaut Logistics) → waterfall → sensitivity slider → export.
What you’re seeing
  1. 01

    Home page.

    The landing view. Scope banner at the top — zero valuation judgments — sets the tool's posture upfront. Five demo fixtures sit in the left sidebar, each modelling a different kind of cap-table mess against a published precedent. The whole app is local-only at 127.0.0.1:5050 — no cloud, no telemetry.

  2. 02

    Open the messy fixture.

    Click "Typical messy" (Pelaut Logistics). The review page renders. Scroll through the Parse Warnings card — the parser found the cap-table tab despite the messy title rows, normalized three date formats to ISO, and skipped two subtotal rows. Below it, the raw-vs-cleaned panel shows what came in alongside what came out. Findings & resolutions below that — every gap surfaced as a card with a field-reference path back to the source workbook.

  3. 03

    Waterfall page.

    Cumulative-payout chart at the top — Y-axis is per-class payout, X-axis is exit value, slope changes mark breakpoints. The dashed vertical lines are the breakpoint set the OPM Backsolve would consume. Below it: the structured breakpoint list and the tranche allocation matrix, both annotated with the rule and provenance for each entry.

  4. 04

    Sensitivity slider — live recompute.

    The What-if scenario panel sits below the chart. Edit a Series B share count from 4M to 6M. Within 400ms the chart redraws with the new dataset and the breakpoint table populates with deltas — the LP-total, breakpoint count, and per-tranche allocation all shift in place. In-memory only; the saved cap table doesn't change.

  5. 05

    Export.

    Scroll to the Export card. One click on the static .xlsx button downloads a clean workbook with cap-table / convertibles / side-letters / breakpoints / findings tabs. Open it in Excel — every share count, breakpoint, and allocation cell is present as a value, ready to drop into an OPM, Backsolve, or DCF. JSON and a live-formula workbook are also available from the same panel.

What it refuses to do

Four design choices that keep the judgment work with the analyst.

The biggest risk with any tooling that touches private-markets data is that it sounds confident while quietly doing the analyst's job. The system avoids that by design — not by hoping the operator knows where to stop.

  1. 01

    The tool never makes a valuation judgment.

    No OPM allocation, no DLOM, no fair-value opinion, no 409A. The tool's job is data hygiene — getting the cap table and convertibles into a state where the analyst can do their work. Every judgment call is surfaced as an unresolved finding, not silently resolved by the system.

  2. 02

    Every finding cites the field it came from.

    Each finding carries a fields_referenced array — share_classes[Series A Preferred].anti_dilution.variant, safes_outstanding[SAFE-2024-A], and so on. A reviewer can verify any flag by opening the source workbook and looking at the named cell. Nothing is hidden behind a black box.

  3. 03

    The analyst resolves; the system recomputes.

    Every finding has a resolve form keyed to the analyst's actual judgment — the SAFE conversion share count, the anti-dilution variant pulled from the charter, the side-letter scope interpretation. The cap table is mutated only by analyst input. The waterfall, breakpoints, and findings re-run after each resolve.

  4. 04

    Outputs are plain files, end to end.

    JSON, .xlsx, and markdown. No proprietary container, no database export. The live-formula workbook has actual SUMIF and IF formulas in the cells, not pasted values — opens in Excel, opens in Numbers, opens in Sheets, and the formula bar shows the math.

What it produced

Findings from a fictional Series B workbook.

These are the four findings the system surfaced on a planted Series B fixture — Pelaut Logistics Pte. Ltd., a fictional cross-border logistics SaaS used as a deliberate stress test. Every finding traces to a specific cell or instrument in the source workbook.

  1. 01

    Anti-dilution variant blank on Series A → blocker.

    The Series A class is flagged before any waterfall math runs. The finding cites the exact field path (share_classes[Series A Preferred].anti_dilution.variant) and explains that broad-based vs full-ratchet materially changes share count in any future down round.

  2. 02

    SAFE outstanding past its conversion trigger → blocker.

    A $400K SAFE issued in November 2024 with a $5M valuation cap should have converted at the Series A close. The system surfaces it with conversion-math guidance and a one-click resolve form — the analyst enters the converted share count, the cap table and waterfall recompute live.

  3. 03

    Option pool last-grant date precedes the most recent round → warning.

    The most recent grant was 2024-06-15; the Series A closed 2025-12-05. Stale grants typically reflect pre-round 409A FMV and an unrefreshed pool size. Surfaced as a checklist item, not a blocker — the analyst confirms or documents the exclusion.

  4. 04

    Vendor warrant referenced in convertibles tab but missing from cap table → warning.

    A 30,000-share warrant struck at $0.20 sits in the convertibles tab and the side-letter tab, but never made it onto the cap table itself. Deep-in-the-money vendor warrants typically belong in the fully-diluted count — flagged so the analyst either adds it or documents the exclusion policy.

Scope

What the prototype covers, and what it doesn't.

ScenarioStatus
Standard NVCA preferred stack (1x non-participating)Built and tested
Participating-preferred with cap (Delaware double-cap)Built and tested
Down-round + triggered anti-dilution ratchetBuilt and tested
Side-letter scope adjudication (text-PDF intake)Built and tested
Indian CCPS / RCPS aliasingBuilt and tested on curated fixture
Class-level cap-table layout (one row per class)Built and tested
Holder-level cap-table layout (one row per shareholder)Known limitation — duplicate class names cause row-level rejection; analyst must roll up first
Tab-name detectionExact-match against a whitelist — non-standard tab names (e.g. "Conv. Instruments", "Co. Info") are skipped silently
Off-charter overrides from side lettersSide-letter terms surfaced as findings; charter values not auto-overridden — analyst records the override during in-session resolution
Convertible-note auto-conversion (cap vs discount math)Not built — too many opinions to be implicit; analyst converts during the mapping step
Multi-currency rounds (mixed USD/INR within one cap table)Not built — currency is metadata at the company level
Scanned-PDF side letters (OCR)Not built — pdfplumber returns empty text on image-only PDFs and warns the analyst to transcribe manually

The prototype is deliberately scoped to the hygiene step. Valuation, OPM allocation, DLOM, and 409A fall outside what it does or claims to do. The known limitations above were caught in testing — including an honest stress test against a fictional Indian D2C cap table built in the holder-level layout common in Qapita's customer base, which the engine intentionally degrades on — and are listed here rather than smoothed over. They're disclosure, not a roadmap.

About

Subhankar Shukla.

Third-year Rotman Commerce student at the University of Toronto, CFA Level 2 candidate (Nov 2026). Builds AI-powered finance tooling on the side. Most recent production project before this: AXIOM — an institutional valuation platform with multi-stage DCF, comps, RAG over SEC EDGAR 10-Ks, and AI-generated investment theses.

Open to extending the framework — additional preferred structures, new checklist categories, integration with existing diligence flows. Reach out anytime.