Status: design of record, 2026-07-28. Vision: 00-VISION.md · Continuity: 16-CONTINUITY.md.
Two intake surfaces still assumed the user was a job applicant. Fixing the answer prompt and the retrieval path (16 §9) stopped BrainCue behaving like an interview copilot; this stops it asking like one.
ContextPackKind (job | subject | project | meeting | personal | game |
custom) existed in the types from the v2 schema work and meant nothing in the
product: jobs:save never accepted it, every row was created as 'job', and
the form asked for an Interview name, a Client / company, and a Job
description. Setting up a Space for a Tuesday standup meant filling in a job
description.
The fix is a relabel, not new columns. The underlying shape — a name, a counterparty, one defining document, a link worth reading, free notes — was always general; only the words were job-specific:
| Column (physical name is v1 legacy) | What it really is |
|---|---|
title |
what this Space is called |
company |
who it involves |
jd_text |
the document that defines it |
company_url |
a page worth reading for background |
notes |
anything else, shown in the Cue Card during the session |
So each kind supplies its own vocabulary (shared/spaceKinds.ts) over the same
storage. Every Space stays in one table, one retrieval path, and no migration.
A kind whose config is missing falls back to custom rather than throwing, so
v1 rows and hand-edited databases keep working.
Two pieces of machinery are gated, not generalized, because they only mean something for a job:
New Spaces default to meeting — the daily case. The kind is fixed after
creation: the Space’s documents are already indexed under it, and quietly
re-interpreting an indexed corpus is worse than asking the user to make a new
Space.
Since (2026-07-28): a kind is now called an activity, and it is also what the start flow asks for — a Space is a saved activity. The catalog moved to
shared/activities.tsand gained the engine mode, the default audio source, and the résumé requirement per activity, plus asoloactivity for working alone. See 18-ACTIVITIES.md.
Onboarding asked for a target role, a target company, an interview type, and a résumé — everything a job applicant needs and almost nothing a companion in someone’s daily calls does. A résumé is a record of what someone did for employers. Standing in for a person requires what they are doing now.
profiles.about (migration 0013, additive JSON) holds what actually changes how
well BrainCue can help:
| Section | Why it earns its place |
|---|---|
| What you do / where | the baseline every answer is framed against |
| Where you are based | so “tomorrow morning” and “end of day” mean something |
| What you are working on | the single biggest predictor of what a call is about |
| Who you work with | names that entity recall can attach to |
| How you work | “never commit to dates in a call” changes what it says, not just how |
| Anything else | the things a stand-in would need and would not guess |
Every section is optional. A half-filled profile grounds far better than a blank one, so the UI asks rather than demands and shows how much is answered.
Each answered section is indexed as its own profile chunk, led by the person’s
name and a phrase naming the section, so a retrieved fragment reads as a
statement about them rather than an orphaned sentence. Clearing a section
removes it from the index on the next save — this is the user’s description of
themselves, and it must be as easy to retract as to give.
reindexProfile clears every unscoped chunk before writing fresh ones. That set
had already grown once (STAR stories are managed separately), and conversation
archives were unscoped whenever the session had no Space — so editing your name
would have silently erased every archive of every call you had ever had. No
error, no symptom, until answers quietly stopped citing last week. Archives are
now excluded explicitly, and the exclusion has a test that fails when it is
removed.
Archives are always Space-scoped now (16 §15), which would
have prevented this bug — but the exclusion stays and is still keyed on
source_type rather than scope, because every archive written before that rule
is still unscoped in existing databases.
targetRole, targetCompany,
interviewType, jdText, and parsedJd still sit on profiles. They are
live for interview mode and dropping them needs a migration against real
databases plus a decision about what replaces targetRole in the answer
prompt. about is additive precisely so this could ship without that.