Sanitization by Construction: Bounded Context Before the Network

Sanitization by Construction: Bounded Context Before the Network

posted Originally published at www.openportfolio.co.uk 2 min read

Sanitization by Construction: Bounded Context Before the Network

Regex redaction on arbitrary broker exports fails the moment a column renames, a locale shifts decimal separators, or a merged cell appears. We chose structural exclusion: the Ask AI path never serializes a free-form ledger string because we never build one for the model.

The mechanism is buildPortfolioContext in app/lib/ai/contextBuilder.ts.


Edge Compiler = function contract, not a package

Edge Compiler is a term of art for this deterministic reduction. There is no EdgeCompiler npm module — only a pure function with a fixed output template:

const TOP_HOLDINGS_COUNT = 10;
// ...
lines.push('Portfolio summary (for personalization only):');
lines.push(`Total positions: ${totals.totalPositions}`);
lines.push(`Total trades: ${trades.length}`);
// Top holdings: ticker, shares, currency, value %, P/L %

Source comment (accurate):

// No raw ledger rows, no PII, no account identifiers—sanitization by construction.

Two pipelines — do not conflate

Stage Input → output What crosses the network for Ask AI
Import Broker CSV → Trade[] via packages/importer Not the default Ask AI body (Part 5)
Context build Trade[] + positions → template string Yes — bounded aggregate only

Import may touch account-ish columns while parsing; the inference boundary is the second stage. By the time buildPortfolioContext runs, only template fields can appear in the output lines.


What the LLM receives

Approved: “The LLM receives a bounded, user-approved aggregate context payload.”

Prohibited: “AI never sees your data.” The model also receives the user message, optional attachment content (explicit user action), and route-defined server injections (e.g. live quotes) per app/api/ai/chat/route.ts and docs/IP-TECHNICAL-MECHANISMS.md.

Approved: No PII and no account identifiers on the Pocket Analyst inference path as designed in contextBuilder.ts.


DevTools receipt

On a typical allocation question:

  1. Client calls buildPortfolioContext(trades, positions).
  2. Network tab shows a short context field in the POST body — not 10,000 trade rows.
  3. Compare to guest localStorage or Firebase-backed trade count in application state — orders of magnitude larger than the payload.

Performance

Reduction is O(n) over trades for position derivation plus sort of position list for top-N — typically milliseconds on-device. Publish latency numbers only after measurement on target hardware.


Part 2 of Sovereign Ingestion & Stateless Inference.

Read the full Sovereign Intelligence book, explore Open Portfolio, or try Pocket Portfolio.

More Posts

Sanitization by Construction: The "Edge Compiler"

Pocket Portfolio - Apr 13

I’m a Senior Dev and I’ve Forgotten How to Think Without a Prompt

Karol Modelskiverified - Mar 19

Your AI Doesn't Just Write Tests. It Runs Them Too.

Kevin Martinez - May 12

The End of Data Export: Why the Cloud is a Compliance Trap

Pocket Portfolio - Apr 6

Everyone Was Talking About Context Engineering. Nobody Had Solved Governance.

Flamehaven - Mar 25
chevron_left

Related Jobs

View all jobs →

Commenters (This Week)

1 comment
1 comment
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!