The Architecture of Invariant Boundaries: One Deployment, Two Audiences

The Architecture of Invariant Boundaries: One Deployment, Two Audiences

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

The Architecture of Invariant Boundaries: One Deployment, Two Audiences

Procurement teams ask whether Open Portfolio is a separate product codebase. Engineers ask whether Pocket and Open can drift into incompatible releases. Both questions have the same answer in our monorepo: one Next.js deployment, one Vercel project, host-aware routing at the edge.

This is not a metaphor for “multi-tenant SaaS.” It is observable middleware behaviour you can curl after deploy.


What “dual surface” means in code

Surface Canonical host Route tree Audience
Pocket Portfolio www.pocketportfolio.app Default App Router product routes (app/landing, dashboard, tools) B2C terminal · adversarial test harness
Open Portfolio www.openportfolio.co.uk app/open/* (rewritten on Open hosts) B2B / procurement / engineering narrative

SSOT for host lists and marketing claims: lib/canonical-claims.ts (OPEN_HOSTS, OPEN_CANONICAL_HOST, positioning strings). Runtime gate: middleware.ts plus lib/surface-host.ts helpers.


Middleware: the invariant boundary

On an Open host, non-canonical hostnames get a 308 to www.openportfolio.co.uk so crawlers consolidate duplicates. The canonical Open host rewrites outward paths to app/open/<path> — the B2B chrome and metadata live in that route group.

On Pocket, paths under /open/* redirect to Open canonical URLs (permanent consolidation). Consumer-only routes on an Open host (e.g. dashboard) 307 back to Pocket so procurement visitors do not land in retail product flows by accident.

Local dev: open.localhost mirrors production host logic without editing /etc/hosts — browse Pocket at localhost:3001 and Open at open.localhost:3001.

API caveat (deploy gate C3): /api/* bypasses the middleware matcher by design. APIs are origin-agnostic; auth flows that assume a Pocket origin must be smoke-tested on both hosts after every production train. See docs/command/deploy-production-gates.md.


app/open/page.tsx is the procurement front door

The Open landing is not a stub redirect — it is the infrastructure narrative surface: sovereign ingestion, importer npm stats, design challenge, architecture deep-links. Pocket’s landing (app/landing/page.tsx) remains the high-velocity B2C harness (Part 6). Same repo, different host, different hero story.


What we do not claim

  • Two production codebases — false; one monorepo, one deploy artifact.
  • “Zero server” for signed-in users — false; Firebase remains authoritative for authenticated trades (Part 4).
  • Open as a separate company stack — false; it is a host + route surface on the same deployment.

Verify after deploy (Product gate)

From docs/command/deploy-production-gates.md:

  • https://www.pocketportfolio.app/architecture301 to https://www.openportfolio.co.uk/architecture
  • https://www.openportfolio.co.uk/dashboard307 to Pocket dashboard
  • Both sitemaps return 200 on their respective canonical hosts

These curls are the invariant boundary receipts — marketing copy should never outrun them.


Part 1 of Sovereign Ingestion & Stateless Inference.

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

1 Comment

0 votes

More Posts

Local-First: The Browser as the Vault

Pocket Portfolio - Apr 20

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

Pocket Portfolio - Apr 6

Split-Brain: Analyst-Grade Reasoning Without Raw Transactions on the Server

Pocket Portfolio - Apr 8

TypeScript Complexity Has Finally Reached the Point of Total Absurdity

Karol Modelskiverified - Apr 23

Systems Thinking: Thriving in the Third Golden Age of Software

Tom Smithverified - Apr 15
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!