Skip to content

Latest commit

 

History

History
121 lines (99 loc) · 5.88 KB

File metadata and controls

121 lines (99 loc) · 5.88 KB

flat-mate architecture

Authoritative spec: docs/design/squad-audit-v1.adoc (decided 2026-06-11). Where this document and the design doc disagree, the design doc wins. This document describes what is actually in the tree and the target it is moving toward.

Current layers (as built, 2026-06-11)

The repo currently contains two architectures side by side. The apps are wired to the legacy one; the new engine is a library not yet consumed by any app. That gap is real and deliberate — do not document it away.

Layer A — legacy v0 marketplace (apps wired to THIS)

A swipe + listings flow over VerisimDB:

  • API (apps/api, Deno TypeScript — the approved 4-file carve-out) provides routes for profiles, swipes, listings, and matches.
  • Web (apps/web) and Mobile (apps/mobile, Expo) consume the same API contract over HTTP. Neither app imports the matching engine directly.
  • Shared legacy modules (packages/shared/src/domain.js, encoding.js, constants.js) own validation, the v1 compatibility scoring, and vectorization.
  • The apps have no tests.

Persistence model: entities are stored as VerisimDB hexads using the document + optional vector modalities.

Entity kinds: flatmate_profile, flatmate_listing, flatmate_swipe.

Payload encoding strategy (intentionally pragmatic for current VerisimDB API constraints):

  • Add searchable tokens (flatmate_profile, borough_camden, etc.) to the hexad title.
  • Append a base64url payload to the title for deterministic decode on read.
  • Keep the body as human-readable JSON for audit/debug.

Legacy matching flow: create profile → deterministic 384-dim vector → write to VerisimDB → feed endpoint ranks via vector search + compatibility re-score → likes/dislikes stored as flatmate_swipe → mutual likes become matches. Legacy listing flow: post listing with borough/rent → stored as flatmate_listing → queried via text search + API-side filters.

Layer B — engine v2, the Squad Audit matching library (NOT wired to any app)

packages/shared/src/matching/ is a pure-JS, side-effect-free library (10 modules + 5 test files, 35 tests passing). It implements the design doc's engine spec:

  • Behaviour vs tolerance as separate, directional variables per dimension; the weakest direction governs (min(fit(A.behaviour → B.tolerance), fit(B.behaviour → A.tolerance))).
  • Feasibility and harmony as split sub-scores, never blended; budget pairs score by overlap coefficient.
  • Banded verdicts (strong / workable / risky / not_viable) instead of raw integers; hard dealbreakers test the other's behaviour, never their tolerance.
  • auditGroup (group.js): full pairwise matrix, budget by intersection (never mean), dispersion detection (split groups reported as split, not averaged), shared-space forecast = minimum member cleanliness with friction nodes named, weakest pair named.
  • Conceal lattice (conceal.js): disclosure tiers T0 (band) / T1 (relational) / T2 (full), with effectiveTier(a, b) = min(a.tier, b.tier) reciprocity. Mirrors the formally verified Idris2 disclosure core in proven-servers (protocols/proven-epistemic; ADR: proven-servers/docs/decisions/0002-add-proven-epistemic-disclosure-core.md).
  • Artifact generators: agreement.js (house agreement draft from the group's actual divergence points, plus universal access-&-needs and guarantor sections — zero stored signal) and brief.js (search brief with budget intersection, move-in window, HMO licensing note).
  • Deterministic seeds (seed.js), including the deliberately broken "Bloomsbury Three" fixture (contains internal dealbreaker kills) as a labelled regression case.

Engine version: ENGINE_VERSION = "2.0.0" (matching/constants.js).

v1 target architecture (from the design doc; not yet built)

The v1 product is the Squad Audit: an already-formed group gets a harmony + feasibility audit, an auto-drafted house agreement, and a search brief — upstream of SpareRoom, no listings. Target wave: Jan–May 2027 London second-years.

The server target is an epistemic-typed server on VerisimDB:

  • Every stored field registered with governance metadata {purpose: identity|feasibility|harmony|agreement, revealingness: low|moderate|sensitive, minTier: 0|1|2}.
  • That registry is the single source for read-time tier gating, the conceal lattice's redaction rules, and the future retention schedule / DPIA documentation (Art. 25 data-protection-by-design — a risk reducer, not a compliance exemption).
  • No UK GDPR Art. 9 (special-category) fields by schema construction — e.g. no accessibilityNeeds free text; universal unconditional agreement/brief sections replace stored sensitive signals.
  • Product copy and mechanism design never promise a "stable matching" — nonexistence is the typical case for roommate markets at scale (Chin & Michelen 2026); see the theory-constraints section of the design doc.

Wiring path (none of this exists yet): apps move from the swipe/listings contract to group-audit endpoints backed by engine v2 plus the field-governance registry; legacy v0 stays in-tree as legacy until a quarantine/removal decision.

Key assumptions

  • Single-city launch (London) is hardcoded by design in the legacy constants (packages/shared/src/constants.js); the audit flow itself is location-light, with borough prefiltering deferred until discovery lands.
  • Auth is out of scope for the first instance; userId is client-supplied.
  • Matching rules live in packages/shared/src/matching/ and never in UI components; the conceal/redaction layer lives in the engine module for the same reason.
  • VerisimDB availability determines persistence (sole persistence layer — estate invariant).