D1
Hybrid event sourcing: immutable event log + state tables, strongly-consistent reads
Where event-sourcing.md
The canonical record of design decisions for IRL. Each entry is summarized here with a pointer to the note that holds the full reasoning — the notes are where context lives; this register is the index.
Decisions are revisable. Every entry is a current best call, not a permanent commitment — especially before we have real user interactions and results. The process for reviewing this register and changing the system in response (small tweaks to large pivots) is itself first-class work, deliberately deferred for now — see Governance below. Known weaknesses, gaps, and inconsistencies from the consolidation critique are tracked in open-risks.md (corrections applied + decisions still needed).
Hybrid event sourcing: immutable event log + state tables, strongly-consistent reads
Where event-sourcing.md
Workshop mode is a runtime flag on a single env, with seams defined up front
Where workshop-mode.md
Onboarding is an AI-guided adaptive interview: adaptive cards, purpose-aware (multi-door), seed-now-grow-later
Where onboarding-interview.md
Per-turn structured-output calls (Opus 4.8), not tool use; non-streaming; one extraction call at the end
Where onboarding-interview.md, onboarding-prompt.md
OnboardingCompleted is distinct from UserProfileCreated; per-turn calls are ephemeral, one event on completion
Where onboarding-interview.md
The user model represents person–situation fit, not traits: three layers (narrative / annotated index / earned relational); stories not ratings
Where user-model.md
Provenance: observed > inferred > stated, with decay; a fresh user correction temporarily outranks stale observations; resolution mechanism TBD
Where user-model.md
Compatibility is not a goal: hard constraints + weak soft priors + revealed signal; never a score; computed pairs-in-context; backstage but legible to the subject
Where user-model.md
Difference is bridged, not sorted by; never model or match on protected/sensitive characteristics; answer the concern honestly when raised
Where user-model.md, coaching-and-engagement.md
Barriers never filter event visibility; barrier-affected events are clearly marked and attendable anyway
Where user-model.md
Anti-observation principle: do-not-interact relationships are information-symmetric and never a tracking vector
Where user-model.md
Not-for-profit posture; members and their information are never a revenue source
Where user-model.md
Re-derivability → persistent narrative storage, with privacy controls (legibility, export, shredding) shipping alongside the model
Where user-model.md
Coaching is circumspect: perspective not instruction, ≤1 per interaction, earned by context; active engagement (proposing/mediating) with guardrails
Where coaching-and-engagement.md
The AI voice is warm but has no name, persona, or avatar; self-effacing and outward-pointing; a global rule across every AI-voiced surface
Where coaching-and-engagement.md
Onboarding feels like a short, warm, guided flow with a clear end — adaptive per card, but not an open conversation
Where onboarding-prompt.md
Warm, not familiar: warmth is in manner, not commentary; the voice never validates, reassures, or interprets the user's experience. Provisional — validate against real reactions
Where coaching-and-engagement.md
Examples and the closing next-step are grounded only in real events provided to the interview (tiered: this locality → nearby areas → canonical fallback); the model never invents events
Where onboarding-prompt.md, onboarding-interview.md
role is stored as a single scalar at onboarding (v1); per-context role is deferred to Layer 3 refinement
Where onboarding-prompt.md
Debrief is tiered — fast tap core (no LLM) + optional AI depth (one call); outcome framed as repetition-intent ("worth another go?") and affinity, not star ratings
Where debrief.md
People-affinity is backstage only — no "who liked you"; capture is positive-only (no per-person "no"); negative is inferred conservatively and never shown; mutual quietly shapes co-suggestion and seeds crews; bound by anti-observation ("backstage" = no who-liked-you surface, not a claim that real-world effects are unobservable — matching.md)
Where debrief.md
A bad experience that is a safety concern routes to reporting and care (Group 4), never treated as preference signal
Where debrief.md
IRL speaks as "we" (the community/organisation), never "I" (an individual) — global across all AI-voiced surfaces; reinforces D15
Where coaching-and-engagement.md
The debrief is information, kept separate from reflection (optional) and coaching (conditional) — it opens a door to them but never performs them inline; closes are minimal, and the user is asked to help refine only after a poor experience; chips are adaptive, opt-in sequences
Where debrief.md
Reflection and coaching are distinct, optional, user-led modes reached (v1) only from the debrief; reflection = IRL listens/asks and grounds patterns in the user's own words (no interpretation, advice, or claims); a ReflectionRecorded event carries the transcript + observed deltas
Where reflection-and-coaching.md
Coaching is conditional — only when a user is stuck on the negative; ≤1 perspective, offered not instructed, frequency-capped (never repeat one), yields immediately; holds the no-demographic line without forcing a reframe
Where reflection-and-coaching.md
Perspectives are framed modestly (general "a lot of people…"), never as empirical IRL-data claims, until real outcomes can ground them
Where reflection-and-coaching.md, debrief.md
Demographic affinity lives on the event (organiser-defined, self-selected), never the user; IRL never collects/infers/matches user demographics; user-level demographic matching stays a firmly-closed door. IRL never enforces or verifies demographic membership (no attendee-verification flow); oriented framing is allowed, real-world gatekeeping is the organiser's, closed groups use invite-only access; IRL's only levers are listing-language policy + honest attendee disclosure
Where user-model.md, organizer-engagement.md
Skills development (conversation-starting first; also empathy, conflict resolution, facilitation) is a first-class capability backing reflection/coaching. Conversation is a growth destination, structured events are scaffolding; unstructured events are a special case needing prep / organiser structure
Where reflection-and-coaching.md, organizer-engagement.md
Framing principle — every "IRL doesn't do X" is paired with "here's what we do / the path that serves you"; never a bare refusal, never implying the user is biased
Where coaching-and-engagement.md
Organisers are first-class. Engagement applies fully to community events (external → source/operator vetting; platform → internal); two modes — invited (collaborative, most of it) and required (gating: exclusion/legal/conduct), kept distinct, boundaries always paired to a path; trust-graduated (scales down with track record); organiser debrief is its own flow (OrganizerDebriefRecorded) that also aggregates attendee signal back as constructive feedback
Where organizer-engagement.md
Event policy: the line is honesty + non-coercion, not subject matter. Open/lenient on topic (faith, politics, advocacy, campaigning, networking, fundraising welcome as genuine gatherings — IRL doesn't police viewpoints). Not allowed: dating-as-primary-purpose, deception (misrepresented events), high-pressure recruitment/sales, IRL-as-commercial-channel (cost-recovery — donations / suggested / small fees — is fine; purpose not price), unlawful/hostile-exclusionary, unsafe/illegal. Enforced via clear policy + encouraging honest wording + lenient default + attendee-debrief flags (not-as-described / high-pressure) + follow-up feeding contributor rating
Where event-policy.md, debrief.md
Invite-only/private events deferred for v1; when revisited, framed as crew/group continuity (privacy-preserving follow-ups for people who met openly on IRL — the repetition engine), not general private events; guardrail: deepen open connections, never start a hidden group
Where organizer-engagement.md
Paid events: suggested cost-covering donations allowed up to $20 per attendee, per event occurrence (each meeting of a recurring event is its own occurrence); fixed-price threshold set per community with community feedback (deferred, no fixed number); cost disclosure required at propose time (amount + what it covers, in the listing); covert commercialisation watched by pattern (collection frequency × amount × attendance across an organiser's events → outliers to human review), deliberately not a per-organiser dollar ceiling
Where event-policy.md, organizer-engagement.md
Contributor rating is backstage, multi-faceted (reliability / positive participation / organising quality / trust-safety flag), built from observed signal with decay and newcomer benefit-of-the-doubt; informs but never dominates outcomes and is never a visible score/leaderboard; positive ≠ popular; safety facet is human-reviewed with due process, and consequential actions carry a reason + recourse
Where contributor-rating.md
The rich user model + contributor rating are an async DynamoDB-Streams projection into a per-item irl-user-model store (fixed-shape data in a few core items, variable collections one item each), separate from the synchronous irl-users basic-profile row; precedence/decay (D7) lives in the projector with optimistic concurrency; narrative isn't duplicated (in the log); fully rebuildable by replay; rating#* access-gated; per-user encrypted + shredded via UserKeyShredded; member legibility = own history (from events), not scores. Replay re-applies frozen deltas (model evolution is a separate batched LLM re-extraction job); decay anchored to event simulatedTime; replay exact only for non-shredded aggregates
Where projection-store.md
Workshop/test mode has an injected LLM seam — deterministic stub/canned Claude provider in workshop & test, real provider in production; robots use canned transcripts. A Group-0 foundation seam, required before any AI flow is testable
Where workshop-mode.md
Matching = fit-first base (works cold, from onboarding) + bounded soft nudges (affinity/rating/crews, each capped below fit) + a preserved exploration / newcomer-injection floor into well-fitting rooms; nothing gates except hard constraints and explicit earned thresholds; popularity confers neither standing nor routing power; numerical scoring is a strawman evolved on long-term results (success now defined — D39)
Where matching.md
Success = real-world connection & belonging, not engagement/retention/attendance. Retention is not a goal (reduced need can be success — the graduation paradox); success is distributional (reach the least-served, not the average); measured as indicators not targets (Goodhart), evolving on long-term outcomes; measurement is consented, gentle, opt-in, backstage — caring, never surveillance
Where success-and-progress.md
Rating uses the welcomer signal, not raw affinity-received: taps generosity-normalized (inverse to tapper's tap rate) and newcomer-weighted; composition-only, never facilitator/organiser/enforcement gates. Raw affinity-received stays captured (capture ≠ use — reversible at the interpretation layer). Resolves open-risks #9; tracked as hypotheses H1–H3 with kill criteria
Where contributor-rating.md, matching.md, hypotheses.md
Hypothesis-driven tuning methodology. Every embedded analysis/scoring adjustment is documented as a falsifiable hypothesis with named tunable parameters (incl. to zero), an evidence/counter-evidence plan, kill criteria, and its anti-patterns — in the hypothesis register. Raw signals are always captured even when unused; the ranking spec is explicit and versioned; continuous tuning targets observed anti-patterns; evidence is observational-first, small-N-honest, Goodhart-disciplined
Where hypotheses.md, matching.md
Event vocabulary reconciled (resolves open-risks #2): UserProfileCreated = profile basics only (name/avatar/vibe → synchronous irl-users row; small step at the interview's close); OnboardingCompleted = sole carrier of transcript + Layer-2 extraction. Cross-env import stays no-history but emits ProfileImported (Layer 1 narrative + as-of-export Layer 2 snapshot) that the projector seeds from; Layer 3 and contributor rating never cross environments (imported users get newcomer benefit-of-the-doubt). Interview is required-by-default in production, structurally decoupled from activation (workshop/robots use the LLM seam, D37)
Where event-sourcing.md, projection-store.md, onboarding-interview.md
Reflection is dual-scope: self-reflection and reflection on the process (the event, structure, venue, IRL itself). Routing: inward → user model, private always; process → evaluation & improvement (hypothesis evidence, model evolution, event/operator register); outward-shareable → explicit in-the-moment consent only, attributed or anonymous at the member's choice (organiser channel). Member-to-member relay (e.g. gratitude) deferred — collides with no-messaging + D21
Where reflection-and-coaching.md, organizer-engagement.md
Reflection entry (resolves open-risks #10): a standing, static "say more" door on every debrief close, wording spanning self and process ("about the event, the people, or how we're doing") + explicit user pull; no proactive dwelling-detection in v1 (needs a classifier call the zero-LLM fast path forbids, and reads as emotional surveillance); revisit with evidence
Where reflection-and-coaching.md, debrief.md
Member-to-member encouragement = structured kudos, never messaging: fixed tappable vocabulary, no free text ever; event-scoped, rate-limited (one per person per event), no replies, recipient off-switch, silent non-delivery (no sender receipts — anti-observation holds). Lives on the past-event surface, never in the debrief (signal hygiene for affinity taps); captured but not used in contributor rating v1 (capture ≠ use). Free-text relay stays deferred. A v-next feature, not v1
Where coaching-and-engagement.md, debrief.md, contributor-rating.md
Declining measurement is never signal — a skipped or declined self-report, check-in, or wellbeing instrument records only a non-response (response-rate accounting); it never feeds the user model, success reads, or cohort comparisons. Symmetric to D22's safety ≠ signal: the consent mechanism must never become the measurement
Where success-and-progress.md
Affinity edges are consumed strength-weighted, never boolean (resolves open-risks #19): each directed tap carries its tapper's generosity weight (the shared H2 transform, incl. small-N shrinkage); a mutual's initial strength = its weaker side (the less selective tapper's weight); repeated chosen co-attendance — above the calendar's chance rate — raises strength regardless (observed beats inferred, D7); tap-derived strength decays faster than co-attendance-confirmed strength; crew seeding accumulates weighted strength. Confirmation is guarded: do-not-interact zeroes the pair's affinity nudge outright, and one-sided engagement caps confirmation gain (a follower can't launder pursuit into affinity). Capture stays raw and positive-only (capture ≠ use); all parameters tunable incl. to zero. Tracked as H4
Where matching.md, hypotheses.md, debrief.md
Graduation is read per-member, never per-group (resolves open-risks #20): fires only for members gone entirely quiet; classifies probable-graduation / left-behind / ambiguous from the member's own signal (mutuality density, trajectory completeness, exit pattern); graduation → get out of the way, never win-back; left-behind → joins the inclusion floor and re-enters via ordinary matching, the inference never surfaced; ambiguous → gentle self-report at most. Backstage; anti-observation holds. Tracked as H5
Where success-and-progress.md, matching.md, hypotheses.md
Comfort-tier avoidance precedence is graduated, never a hard override (resolves open-risks #21): avoidance weight scales with how actively IRL engineers co-presence — soft on passive feed suggestion (the floor wins on a thin calendar), steers room choice for injection when alternatives exist, maximal on intimate composition (the pair is in practice never composed) — but never an advertised guarantee at any surface (no legible negative-space signal); the inclusion floor is windowed (chances over time), and sustained collisions accrue floor-debt to human review (ties to #22). Applies to do-not-interact only — protective blocks are hard (D50). Tracked as H6
Where matching.md, user-model.md, hypotheses.md
Protective blocks are hard, immediate, and above every other mechanism. A block is a hard constraint overriding everything, including the inclusion floor (the floor injects within the feasible set). Victim-initiated, proof-free, instant, silent (the blocked person is never notified); presence-shielding, not event-hiding — the blocker vanishes from the blocked person's view on every surface, while the blocked person's event visibility is never conditionally altered (no negative-space leak). The protective effect is never gated on review; human review governs only consequences to the blocked (enforcement, restriction, removal). Tier line drawn by need, not relationship type — no member proves they qualify. Frivolous/weaponized blocking is met with pattern monitoring + human review, never by weakening protection (asymmetric costs: a weakened block risks physical harm and legal exposure; an unwarranted one costs almost nothing). Block hardness is a commitment, not a hypothesis — no kill criterion. Full mechanism is Group 4 (open-risks #23)
Where matching.md, user-model.md
The supply loop is a standing function at every scale, never a thin-calendar fallback (resolves open-risks #22): matching allocates supply and never relaxes fit to fill the floor — supply, not standards, is the corrective lever. Continuous demand sensing (the fit-gap read across envelope segments — floor-debt is its acute case — plus event-selection signal, debrief texture, process reflections, explicit wishes), surfaced aggregate + de-identified to affected members and trust-graduated organisers, and only above a minimum-cohort threshold (small-community de-anonymisation guard); idea-stage proposals are first-class and bar-free (the quality bar applies to events, not ideas); invitations to propose are D14/D30-bounded (≤1, earned by context, paired don't/do, never pressure); the quality loop grounds propose-time help in observed community outcomes under D27 modesty. Tracked as H7
Where organizer-engagement.md, matching.md, hypotheses.md
Protective-block mechanism v1 (resolves open-risks #23): the rendered-world rule — for the blocked person, IRL renders a world in which the blocker doesn't exist (all surfaces, counts adjusted to match; indistinguishable from having left IRL), while the blocked person's own experience is never conditionally altered (no negative-space leak). The blocker keeps ordinary member power only with a capture-time awareness / peace choice (awareness default — surprise is the danger) and one narrow notification, the itinerary alert (own confirmed events only); nothing broader in v1. Active placement hard-filtered; browse and attendance rights intact (D10). Displacement handled: a blocker's yield after the blocked commits never dents her reliability (auto-quarantined), and displacement/proximity patterns route to human safety review in both directions — never a legitimacy test on the block. Co-presence is the fiction's stated limit (reveals the block's existence, never plans; disclosed at capture). RSVP-ing to a blocked organiser's event is an informed, per-event choice that necessarily reveals roster presence. Block ≠ accusation — no rating/conduct effect by itself; only a separate optional report enters safety review (this is what makes proof-free defensible). Pair signal zeroed at the interpretation layer; no decay or expiry, blocker-liftable only; environment-local (D42 unqualified — migration is workshop→production onboarding only; revisit if that widens). Not a hypothesis — no kill criteria; evolves via advocate-informed review only. Advocate validation planned before build
Where protective-blocks.md, matching.md, user-model.md, debrief.md
External events: steward, not organizer; confirmations are mutual commitments between members. The poster of an external event is its steward ("Listed by", never "Organized by") — responsible for keeping the listing current or cancelling it, holding the existing organizer gates (edit/cancel); stewardship is deliberately light so sharing a flyer never feels like owning the event. No open editing (any-member update is a griefing surface and drags in confirmation workflow/messaging); the correction channel is the existing suggestion system ("moved to 7pm per their site" → steward adopts), with unadopted suggestions doubling as the stale-steward signal (admin surfacing Group 4; "claim stewardship" transfer is the future add if absence bites — never open-edit). Confirming attendance is allowed and encouraged: the commitment is to other members ("you won't walk in alone"), social not administrative — confirmers gain no edit power. External events are born planned (a real event needs no proposal phase; full time/place trio required at listing), threshold/auto-plan don't apply (it happens regardless), capacity is informational only (not IRL's to enforce), cost disclosure (D34) applies, attendee debrief unchanged, no organizer-debrief; not-as-described flags point at the listing/steward and feed contributor rating later
Where external-events.md, event-policy.md, organizer-engagement.md
Finding each other at the venue: recognition text now; anything interactive is a tracked design area, and proximity tech is constrained by D50/D52. Every event (all sources) carries an optional meeting-spot / how-to-recognize-us hint ("back tables, look for the blue scarf") — the zero-tech answer that covers most cases, live now. Richer options recorded, not decided: on-arrival limited interaction (single templated message, at-event-time only — a deliberate, narrow exception to no-messaging if ever built; the messaging-wedge watch-item applies), shared visual symbol on attendees' phones (promising: mutual, opt-in-by-glance, no location data), and Bluetooth/GPS direction-or-distance to attendees — flagged as the dangerous one: a proximity read is a location-disclosure surface that collides with the rendered-world rule (a blocked person's device must never register the blocker's presence, bearing, or distance) and sharpens the co-presence limit D52 accepts; any such feature needs block-awareness, per-event opt-in, and advocate review before design starts
Where external-events.md, protective-blocks.md
Feed ranking v1 — the first implemented, versioned ranking spec (matching-spec.md is the source of truth; matching/tunables.mjs mirrors every default). Hard constraints are the only gate (joinable state, capacity, schedule overlap with live confirmed commitments, already-committed; protective blocks apply here when built). Fit v1 is interests-only (token match against title+description) — deliberately thin and named as such: envelope/doors are free-text annotations and events carry no structured shape, so real fit waits on the event-type register. Affinity nudge is outgoing-only (positive taps, H2-lite generosity self-discount per D47, capped below fitCap — the open-risks #6 invariant is asserted structurally in tests); mutual amplification deferred (needs the otherUserId GSI + full D47 strength model). Exploration = deterministic hash noise (userId·eventId·specVersion·weekBucket, simulated-time anchored, reshuffles weekly) + a guaranteed exploratory share of slots. Ordering is the only output that leaves the server — no score, fit, or nudge in any response. Every deliberate absence (envelope fit, mutuals, crews, rating, avoidance, injection into others' feeds, distance) is named in the spec with the slice it lands in
Where matching-spec.md, matching.md
Every event gets a machine-readable shape, LLM-extracted at propose time and organizer-correctable. One event-shape call (D37 seam; deterministic stub in workshop/test) classifies the listing into activityTags (≤5 free noun phrases), structure (structured / semi-structured / unstructured), and doors (useful / make-learn / connect); the result rides in EventProposed.data.shape frozen at command time and projects onto the event row. Shape is public listing data — not PII, not encrypted. The organizer's edit replaces it wholesale and stamps source: "organizer" (vs "extracted"); nothing re-extracts in v1, so a correction is never overwritten. Extraction failure is never propose failure — a shapeless event ranks via the text-fallback fit tier. Fit consumption (ranking spec v2): activityTags become the high-confidence interest-match tier, doors match structured-to-structured against onboarding door weights; structure is captured, not used until the member envelope gets comparable form (capture ≠ use). The event-type register (operators, venues, safety attributes) remains a separate, future construct — shape describes one listing, the register will describe kinds
Where event-shape-prompt.md, matching-spec.md, matching.md
Crews v1: triads of mutual-strong pairs, formed from weighted co-attendance, consumed as a capped gathering bonus. Formation (async projector, incremental): a crew exists when all three pairs of a triad are mutual-strong — both directions tapped positive AND reciprocal met counts ≥ crewMutualMetPivot (the D47 co-attendance proxy; never tap counts or boolean mutuals — a spam tapper cannot seed a crew). Detected when a debrief lands a positive tap; re-detection re-affirms (continuity is earned repeatedly, not held). Crew rows live on every member's partition encrypted under that member's own key (shredding removes the member's copy). Consumption (ranking spec v4): only a gathering signals — ≥2 fellow members present on a candidate adds crewBonus decayed from lastAffirmedAt; a lone crew-mate is just an affinity edge. Must-not-ossify is structural: crew contribution capped separately (crewNudgeCap), total soft nudges (affinityNudgeCap + crewNudgeCap) asserted below fitCap — a crew tilts its members toward each other, never walls newcomers out. Deliberate v1 bounds, named in the spec: triads only (size-4 via merge later); raw reciprocal counts (chance-rate baseline = H4 tuning); the ossification aggregate read (newcomer-share trend, gaming register) is future backstage work and is where the otherUserId GSI finally becomes necessary
Where matching-spec.md, matching.md
The comfort envelope gets a machine-comparable form: coarse 3-position scales alongside the story, never instead of it. Five dimensions (groupSize, structure, familiarity, role, novelty) each gain an optional position on a 3-value scale plus an optional edgeToward pole (the structured twin of the growth edge); vocabulary lives in one module (lib/envelope.mjs) that extraction, debrief shifts, corrections, and fit all validate against. Sign-off reasoning recorded: the scales use the design's inbuilt vocabulary to drive inbuilt functionality, not classification for its own sake; the analysis orders events per member, never people against each other (people-scoring is where categorization becomes the problem); fit orders, never blocks; and the mechanism is fully transparent to the member. Positions come from three D7-ordered sources: onboarding extraction (optional — restraint over coverage; projector drops unrecognised values), debrief/reflection shiftToward (one story sets a pending marker; a position moves one step only when shifts repeat in the same direction), and member correction. Consumption (ranking spec v5): structure fit via the 1:1 shape map, size fit via attendance banding, known-face comfort as a presence-dependent fit boost (not a nudge) for needs-known-face members; role/novelty captured-not-used until comparands exist
Where profile-and-legibility.md, matching-spec.md
Model legibility: the member sees and corrects what IRL believes about them. GET /me/model renders Layer 2 member-facing — positions, growth edges, doors, interests, strengths, barriers, constraints, each with provenance as plain language ("you told us" / "we've noticed") and the latest story behind it. Deliberately not behind the agreement re-accept gate (legibility is a data right, like export; correcting IS participation, so the correction route is gated). Never shown to anyone, including the member: Layer 3 (affinity, crews, tap stats), contributor rating, any weight or score — enforced server-side; raw store items never travel. POST /me/model/correction emits UserModelCorrected (typed: envelope position/edge, interest add/remove, barrier remove — the one-tap dignity path; barriers are never argued with). Precedence: a correction beats every piece of evidence older than itself, of any provenance; evidence arriving after resumes normal D7. No counters, no expiry clocks — the recorded philosophy: decay by literal timer is unnatural; the member's activity and experience is the real timer; time doesn't reduce the importance of information, only new grounded information does. Watch note: this philosophy sits in tension with spec v4's clock-based affinity/crew half-lives — flagged for future register discussion (evidence-anchored decay), not silently reworked; taken up and resolved as D60 (evidence-decay.md, spec v6)
Where profile-and-legibility.md, user-model.md, evidence-decay.md
Decay is evidence-based: lived events are the axis, floors are the prior, and silence is never conclusive. Replaces spec v4/v5's three clock half-lives. The recorded reasoning: a literal timer is a mechanism preferred for ease over validity ("easier to explain" is part of the ease, not a rationale); the evidence set is known-incomplete — off-platform contact is invisible, members under-report, and normalization can reduce in-platform signaling as a tie strengthens — so the math must respect incompleteness; and absence from a crew signifies ≈ nothing (reconnection routinely feels like no time passed). Mechanism: half-lives count the member's own debriefed events (tap strength and crews on the own-activity axis; confirmed strength on min of both sides' activity since their own last met-mark — divergence only counts when both are living without each other), and every component decays toward a floor, never zero (tap 0, confirmed 0.5, crew 0.5) — below-floor is reserved for grounded counter-evidence (D49 avoidance, D50 blocks). Zero activity → zero decay (the away-and-return member keeps their social graph); recovery on fresh evidence is instant and total; met-without-tap stays captured-not-used (normalization is indistinguishable from cooling — promoting it is a spec bump with H4 evidence, never a silent code path). All parameters tunable including to off at both ends (floor 0 = pure decay, floor 1 / half-life 0 = none). Watch signals: returning-member reconnection, floor saturation, and stale-steer pressure — which routes to prioritizing D49 avoidance capture, never to re-adding clocks
Where evidence-decay.md, matching-spec.md, hypotheses.md
Avoidance capture v1: a tucked-away deliberate act in the debrief people step — never a rating, never visible, soft-only. The comfort tier (D49) becomes capturable: two typed tiers (didnt-click / do-not-interact) behind a ⋯ affordance on a met person — the people step's main flow stays positive-first (untapped remains neutral; no per-person "no" chip — D21 signal hygiene), and a tap+avoid on one person is rejected as contradictory. Capture-time honesty (the matching.md #17 commitment): reduces co-placement, cannot prevent co-attendance, the named person never knows; safety routes explicitly to the conduct question — a person reads that, ranking doesn't (D22: safety ≠ preference; quarantined debriefs carry no avoidance). Stored as the newest word on the member's own edge (a later positive tap clears it; history is never rewritten). Consumption (ranking spec v7): pair strength zeroed either-direction inside edgeStrength; no crew formation, known-face boost, or gathering through an avoided pair; capped de-weight (avoidancePenalty/didntClickPenalty/avoidanceDeweightCap) in the namer's feed only — the room sinks, never disappears (exploration still applies; no negative-space leak). This is the grounded counter-evidence the D60 floors reserve below-floor space for. Deliberate v1 bounds: capture only where paths actually crossed (standalone naming waits for the blocks design and its people-picker questions, D50/D52); Layer 3 — never in the member's own model view (D59); un-naming = the next shared debrief or the future blocks-tier surface. Tracked as H6
Where matching-spec.md, matching.md, debrief.md
Localities are a curated effort-band register, and travel is prioritization, never filtering. The register (lib/localities.mjs, served at GET /localities) models the effort shape of getting somewhere — typed neighbors (easy hop) / crossings (real trip) edges, pairwise bands here/nearby/a-trip/far from direct edges only — no coordinates, no distance math, no transitive reachability; every band is a legible curatorial judgment, and only served localities accept sign-ups (banding a place never widens the launch gate). Events carry an organizer-declared localityId (never LLM-extracted; absent = home). Members state a reach (default anywhere — no silent narrowing) consumed as a graduated de-weight capped below fitCap — the founder's recorded principle: "prioritization, not filtering — you never know when someone wants to travel further for the right event, or on a whim"; the exploratory share ignores penalties (the whim door is structural); nothing gates except true feasibility. Effort is personal: the bands are the community's median judgment; mode/ferry-sociology/non-monotonic-preference variance is deliberately unmodeled in v1 (a wrong band costs ordering, never access) with named watch signals; the member's dial is the reach plus per-locality adjustments (±1 effective band, both directions, captured at onboarding / event detail / the D59 constraint correction). Time windows are structured (4 slugs, classified in the community timezone) and consumed as soft fit only — rhythm is preference, distance is effort, neither gates. "I wish this was closer" is captured (EventWishRecorded, frozen at tap time) and consumed by nothing — the demand side is radar R8; future refinement: per-member × locality observed affinity (D60 spirit).
Where localities-and-constraints.md, matching-spec.md, radar.md
The event-type register: graduated tags, earned by recurrence — and types exist so "worth another go" keeps its promise. Shape describes one listing (D56); the register describes KINDS. The user-first purpose, recorded after it survived the could-we-explain-it test: to the member — "when you tell us something was worth doing again, kinds are how we find you the next one"; to the organizer — "filing it right is how the right people's 'again' finds it"; to us — a filing key, nothing more. Governance decided across four review rounds: tags describe (open, free, organizer-minted), types identify (curated keys — accumulation fragments over open vocabularies); recurring tags ARE the type-proposal mechanism; deterministic assignment from matchTags (no LLM call; most-matched wins, a tie assigns nothing; untyped is first-class), organizer-correctable and never re-derived over; not a taxonomy — flat + one coarse family; evolution at two speeds (matchTags/name = free curation; meaning re-grounds through evidence; real divergence = split, ids never reused); retirement never deletion, never by timer. Dataflow explicit both directions: evidence flows into curation, never directly into assignment; downstream = outcome rows + again-intent fit (flagship: yes full / maybe half / no NOTHING) + novelty fit + organizer picker — and NEVER gating, people-matching, rating, pricing, or public popularity (a type is a key, never a judgment). Attribution honest: a yes is never single-credited (people→affinity, structure→envelope, activity→type); positive-attribution texture chips capture the why in one tap; lastAgain stores its context so the misattribution loop is measurable → aspect-weighted credit is the named refinement. Member-facing display deferred until a surface serves the member; §7's presentation rules bind when it arrives (community's own words, chip never badge, untyped shows nothing, no public popularity). Venues + operators designed with the same discipline, deferred to their volume. Registers describe kinds, never members
Where event-type-register.md, matching-spec.md, debrief-prompt.md
The operator console is in-app and role-gated; support waits for R4; admin convenience never overrides the privacy posture. The Group 4 admin/support item untangled into its two users. The OPERATOR gets five panels (Workshop, Members, Registers, Health, Policy), every action event-sourced with the admin as actor; split-console trigger named (non-admin staff existing). Workshop seeding decided across two review rounds: personas load WHOLE at setup (safe by construction — no directory, no member browsing; rosters are the only exposure surface, so unused personas are invisible) and events are the live selection unit, each carrying pre-set rosters (+ canned debriefs on past events so affinities/outcomes exist); the fixture's localities are SYMBOLIC slots (A/B/C) bound to real register localities in one hit per workshop; facilitators drive personas via per-tab identity isolation (sessionStorage tokens on workshop stacks) + an "open as" list; autonomous robots deferred to R5. Verification is verify-only — declines park with R3 (the method/policy design) + R4 (the communication), with the helpful-decline principle recorded (D30: alternative path or suggest the right locality, never a bare no). Registers render read-only until the strawman trigger; curation/analytics dashboards wait for real or post-workshop data. The admin data discipline: PII minimalism per panel; member models, Layer 3, contributor rating, and debrief content never shown in this console; admin reads are queries, never admin-side copies. Member support builds NOTHING until R4's communication design. (Revised 2026-07-24: the Safety panel added — the ops review's activity register found conductConcern landed on the log with nothing reading it. Conduct-concern queue + event-sourced acknowledgment shipped; the conduct NOTE is the data discipline's one named exception, readable in the Safety panel only — the safety-ops read the quarantine was designed for. Due-process machinery stays Group 4.)
Where admin-and-support.md, workshop-mode.md, radar.md
Launch #1 runs a written playbook; every phase advance is judgment with named inputs, never a threshold. R5 graduated for the FIRST locality — trigger corrected: the first launch runs with no muscle memory, and repeatability is the byproduct of writing the process down and correcting it after one run (a playbook is only validated by a launch). The arc: interest read → founding cohort → advisor round → workshops → soft open → community open → retro-that-corrects-the-playbook. Go decision inputs are reading aids (8–15 committed people against the minimum-3 event floor, an organizer-shaped person besides the founder, interest spread across families, operating capacity) — no-go is a real outcome. Founding cohort: what-they-get/what-we-ask stated honestly incl. the small-N visibility fact (D51's minimum-cohort rule binds hardest at N=12); voice, never knobs (no in-app privileges); gratitude lives outside the product (letter/gift/thanks — no label, no status; labels calcify). The advisor round is where the waiting strawman registers (D62 bands, D63 kinds) get local correction and D52's advocate validation is scheduled — fixing R1's due date (its trigger is this round). Workshops: three scripts consuming the D64 tooling — the member's arc (attendees DO the interview themselves; facilitator switches to a seeded persona only for lived-history beats), the organizer's arc, and the empty room (personas seeded, zero events; the session ends with the room proposing the first real event live — demo becomes launch). Robots v1 scoped: batch automation of pre-defined persona action sets (e.g. wind-past-event + submit canned debriefs as one action), never stochastic automata; not for launch #1; builds with the first self-serve demo stack (SSDS — the workshop machinery handed over without a facilitator, primarily for serious/safety-focused advisors; the adversarial red-team agent on an SSDS recorded as the strongest robot use case, for the safety roadmap). Languages: English-only launch #1, per-community language a scope input to that community's go decision → designed ahead of need (R10). Founder concerns #1/#2 registered as R9 (operating at unstaffed scale) and R10 (languages & localization). Soft open starts R4's clock; served-flag widening is decision discipline, not a code change
Where launch-playbook.md, workshop-crib-sheets.md, radar.md
Feedback lands on decisions or it evaporates; registers grow by contact, never by project. R1 graduated (due before the advisor round D65 scheduled). Coverage gaps closed with two new registers — ux-register.md (U: UX + copy + visual in ONE register while volume is low) and tech-register.md (T: ADR-style rows that index existing notes, never duplicate them) — seeded with a handful of rows to set the bar; record on contact is the growth rule (an entry is written when a call is made, revised, or touched by feedback; retrospective mining is explicitly out of scope — it produces a graveyard, not a register). No ops register until R9. The intake pipeline (feedback-log.md, FB-rows): solicit against something specific per channel → capture verbatim → triage in three cases (touches a recorded decision → cite + keep/revise; touches an UNRECORDED decision → record it first; touches nothing → route to backlog/radar/open-risks/hypotheses — no fourth pile) → land as register edits with dated revision trails → answer back (changed / stands / routed; declines per D30 name the reasoning and what would move it) → reopen only by engaging the recorded reasoning with something new ("I disagree" reopens nothing; observed beats stated applies to design too). Pre-launch the founder decides every reopen — stated plainly; governance proper stays deferred per this register's header. Feedback is evidence, never a vote (D21 applied to design). Firewall affirmed at review: member-signal paths (debriefs, corrections, wishes) and product feedback never mix — product feedback never edits a member's model. The advisor round pack (excerpts + real questions + the intake promise) is the first consumer; the log opens with retro-recorded rows marked as such
Where registers-and-feedback.md, ux-register.md, tech-register.md, feedback-log.md
Every trust-bearing loop gets a deliberate disposition before growth forces one; automation never launders judgment. R9 graduated (worked as the org track's operations strand; mechanics public, roles/staffing private per R11's boundary). The four dispositions: automate (the mechanics AROUND judgment — routing, formatting, measuring — never the deciding: a verification decline is a communication, a safety review is due process, a feedback answer is a relationship), staff (trigger-bound, never calendar-bound), redesign away (the best where it exists — community vouching for verification, trust-graduated organizers for stewarding, register store+tool on the strawman triggers), and operator-for-now with a named failure signal written publicly so the community can see whether we honor it. The public loop map's honest summary: exactly ONE loop is staffing-shaped (conduct/safety review — never fully automated, never solo-forever; a second trained reviewer before multi-community scale), one wants a volunteer (facilitation — the crib sheets make it handable), two want automation now (deploy Lambda; incident runbooks + alerting on the health endpoint's numbers), and the rest are designed-to-stay-small or trigger-named. The watch-item that IS the note: the unstaffable future is a designed-away future only if the redesigns land before their triggers fire
Where operations.md, radar.md
The project runs under the portfolio methodology — declared, pinned, zero deviations. Adopted majodali/methodology v1.0.0: classification.md is the binding declaration (C2 / S2 / web-app / serverless-aws; workflow stages proposed→designed→built→workshop→production with live = production, entry-designation defaults in the backlog header — format local pending the methodology's own calibration). The three adoption tensions were resolved by changing practice, not recording deviations: single-use outcome-named branches (W-006) retire the reused session branch; branch protection lands on main instead of declaring the deploy-on-push posture; C3 promotion (re-classification + K-009 hosted decision/risk register views) is bound to soft open as a launch-playbook §6 gate — real members ARE the C2→C3 boundary. Plan discipline adopted forward (K-007/W-001): arc-scale work gets an outcome-named statused plan in docs/plans/ with founder-set chunk gates; slice-scale work keeps the tight-increment loop. CLAUDE.md stays a pointer; nothing under .claude/ is authoritative (K-001)
Where classification.md, launch-playbook.md §6, methodology
The registers are published as generated, hosted, latest-snapshot views — the markdown stays the source of truth. K-009's hosted views (decision + risk registers, the C3 gate) are built by a zero-dep renderer (infrastructure/scripts/render-registers.mjs) regenerating /registers/ on every site deploy — "kept current" is a deploy-path property, not a process. Three pages only (index with the K-008 supporting explanation + D66's answer-back promise, decisions, risks); latest snapshots with generation date + revision, GitHub as the historical record; open-risks renders verbatim — the frank defect list IS the public window's honesty; workshop stacks serve the same pages (public data by construction); register tables render as entry cards, every D-row asserted by test so register drift fails the build. Advisor-pack excerpts reuse the renderer (one build, D66)
Where hosted-register-views.md
Flagged as needed, deliberately not designed yet:
hypotheses.md) and modify the system in response to real-world results, from small tweaks to large pivots: cadence, who decides, and how a change propagates back through notes, prompts, and code.success-and-progress.md): a rotation cadence, and a "how would this number be force-produced?" review before any indicator informs tuning. The Goodhart defences are otherwise purely procedural and depend entirely on this cadence existing (scenario-walkthroughs.md #11).Deliberately not solved now, but tracked — a reminder that a system like this always produces unintended consequences and modalities:
debrief.md → When a user steers somewhere we won't go) — needs careful wording and real-world validation.success-and-progress.md).matching.md), but watch it in practice.scenario-walkthroughs.md F3).event-policy.md).