The relationship summary
relationship_console.story answers one person across every channel and every stage change, newest first: their record, the assembled history, the journey summary, and whatever sales holds for them. It is composed when you ask rather than stored, and the text inside it passes a name guard that removes a form of address standing where a name should be.
What goes into one#
- The person — display name, company, and the current stage with its label.
- The history — the assembled timeline for that person, newest first, bounded at 200 entries by default.
- The journey summary — where the relationship has got to and how it got there, from
journey.py. - Selling — the opportunities and demos
sales.for_personholds, which is a question the summary asks rather than a thing it owns.
That last one has a deliberate fallback. A workspace whose database predates the sales tables still gets a person's history rather than an error — the summary degrades to what exists instead of refusing to render. It is a small decision that separates a screen which is occasionally incomplete from one which is occasionally blank.
Composed, not kept#
There is no summary document sitting in a column waiting to go stale. Every part is read at the moment of the request, so a stage moved a minute ago is in it, and a case resolved while you were reading is resolved the next time you look. The trade is query cost, which is why the assembly is set-based rather than a loop — the same lesson the timeline page carries the measurements for.
It also means there is nothing to regenerate after a merge. The merged record simply reads more, which is why a summary can look as though it grew a year of history in one step.
The name guard#
Text about a person accumulates over months: call summaries, notes, memory lines, follow-up reasons. Some of it was written before Connect learned that a respectful form of address is not a name, so a stored line can read *The prospect, Andi, is interested* where *andi* is an honorific, not a human.
| Moment | What it does |
|---|---|
| A person record is created or updated | clean_name returns nothing at all when the value is a role word, an honorific or an acknowledgement, so it is never stored as a display name |
| A memory is written | The title and the body are rewritten before they are saved |
| A call summary or a follow-up reason is written | The same rewrite runs on the text |
| The stored relationship is read back into a briefing | It is scrubbed again, because rows written before the guard existed are still on file |
The rewrite is positional, not a deletion of words. *The prospect, Andi, is interested* becomes *The prospect is interested*; a real name in the same position is untouched. The rejected list covers honorifics and kin terms, acknowledgements and fillers, discourse words, and role words like *caller* or *client*, in English and in Telugu and Devanagari script.
What it is not#
- Not a report you can edit
- Correcting the summary means correcting what it reads: the memory, the notes, the stage. Editing prose that is recomposed on every request would last until the next request.
- Not a substitute for the timeline
- The summary is oriented to *who is this and where are we*; the timeline answers *what happened, in order*.
- Not cross-workspace
- Isolation holds here as everywhere: one workspace's summary reads that workspace's records only.
- Not the same as the contact brief
- A channel is given a much shorter block with its own budget — see the contact brief.
Questions#
How often is the summary rewritten?
It is not written on a schedule at all — it is composed each time it is asked for. There is no refresh interval, no queue, and no stale version to notice.
Why does the summary call somebody 'the caller' when I know their name?
Because the stored text had a rejected word in the name position, or the name was never captured as one. Setting the person's display name fixes it going forward; the guard leaves genuine names alone.
Can I stop opportunities appearing in it?
The summary asks sales what it holds for that person; it does not decide what is on the pipeline. Closing or removing the opportunity in sales is what changes the answer.