# A fact learned on a call, end to end

A fact said on the phone becomes contact memory at the end of the conversation, through `voice.end_call`, and is read on every channel from the next piece of work onwards. Between being spoken and being stored it passes a summariser floor, a name guard and — for a number, an address or a code — a read-back check. Anything that fails one of those does not become a fact.

- **Status:** Available
- **Audience:** both
- **Channels:** phone, email
- **In the app:** #/calls, #/relationships, #/inbox
- **Last verified:** 2026-09-10
- **Canonical:** https://connectbyjbrh.com/docs/workflows/memory-from-call-workflow/

## The stages

1. TRIGGER — the line rings inbound, or `chase_phone` drains a phone follow-up and places the call
2. USER / EXTERNAL EVENT — a person speaks; `start_of_speech_sensitivity=HIGH` means a one-word answer starts a turn
3. AUTH / WORKSPACE RESOLUTION — the signature is checked and the handler runs inside the owning workspace, not merely beside it
4. INGEST / REQUEST — the worker posts each spoken sentence to `/api/voice/engine/spoken` and each event to `/engine/event`
5. CANONICAL RECORD — the `calls` row, plus `call_events` storing every normalised event once behind a partial unique index on the signature nonce
6. CLASSIFICATION / RESEARCH / REASONING — `entity_heard` names a spoken value and the next two lines are checked for a read-back
7. KNOWLEDGE + MEMORY + RULES — the brief was rendered once at the start; nothing written now reaches this conversation
8. AUTONOMY / APPROVAL — a promised time is refused unless it shares a time word with what was said, or was agreed aloud
9. ACTION / PROVIDER — the model answers; the reply is re-checked against the guardrails after the fact
10. RESULT — the conversation ends and `hangup_by` is attributed to caller, model, owner, engine, carrier or agent
11. RELATIONSHIP / TIMELINE / MEMORY — `/engine/end` runs `voice.end_call`: summary, lead, memory, follow-up, with the digest deferred to a background task
12. AUDIT / USAGE / NEEDS YOU — model usage is booked into `costs`, and line health escalates into Needs You when a line stops being reachable

## Stage by stage

| Stage | What you see | What changes | What can fail |
|---|---|---|---|
| The line rings | An active conversation on the Phone screen | A `calls` row exists | `not_ready` when no worker has checked in for 90 seconds, so the drain retries |
| A value is spoken | Nothing on screen | An `entity_heard` event naming what was heard | A misheard digit that is never read back |
| A time is promised | Nothing on screen | A follow-up, or nothing at all | The tool answers **NOT recorded**, so no booking is claimed |
| The conversation ends | The record closes immediately | Cost booked, digest marked pending | Nothing — the digest runs separately, so a slow model cannot lose the ending |
| The digest runs | Summary and any memory appear | Contact memory is written | Below the floor, nothing is summarised at all |
| A week later | An email reply that knows the fact | Nothing new | The memory was written on a different person record |

## The three checks between spoken and stored

1. **The floor.** Fewer than two spoken lines and fewer than five words from the other party, and nothing is sent to the summariser. Ten one-turn records once carried an invented afternoon at the sales desk; not asking is cheaper than correcting.
2. **The name guard.** `PROTECTED_MARKERS`, `name_rejected`, `clean_name` and `scrub_names` stand on every door a name passes through, including `connect_memory.remember`. A form of address is never a name, and `fact_rejected` refuses a fact keyed to a pronoun, a suffix or "the caller".
3. **The read-back.** A number, an address or a code gets an `entity_heard` note and the following two lines are examined for confirmation, recorded as `entity_readback {confirmed}`. An unconfirmed value is exactly what you would want a person to look at before it becomes durable.

None of the three makes a transcript trustworthy on its own. What they do is stop the two failure modes that damage a relationship: a confident wrong name, and a fact invented out of an outage.

## Using it on another channel

Contact memory belongs to the **person**, not to the number they rang from. So a preference stated on the phone on Monday is in front of Connect when the same person emails on Friday, provided the two resolved to one person record. That is the payoff for the identity work: a contact created by lead capture carries `phone_key` from the start, and a number matching two records resolves to the oldest rather than quietly starting a third history.

The failure to look for, when a spoken fact does not turn up on email, is almost never memory. It is two person records for one human. Merging them in [relationships](/docs/relationships/) restores it everywhere at once.

## Questions

### How long after a call does the memory appear?

The record closes immediately and the digest runs as a background task, so the summary and any memory follow a moment later. That split exists because the ending used to wait on two model calls inside one twenty-second request and log 'end not recorded' for an ending that had in fact been recorded.

### If nobody answered, does Connect record anything about the person?

No facts and no lead. A conversation that never happened has its own word: `no_answer` rang and nobody picked up, `not_reached` never rang at all. Keeping those apart stops an outage being written down as a fact about somebody's willingness to talk.

### Can I correct a fact the call got wrong?

Yes — edit or forget the row at the contact tier, from the viewer or the memory sheet. It changes the next piece of work on every channel. If the error was a name, check the person record as well, because a wrong name is usually a wrong identity match.

## Related

- [Memory from a phone call](https://connectbyjbrh.com/docs/memory/memory-from-call/)
- [Person memory](https://connectbyjbrh.com/docs/memory/person-memory/)
- [How memory reaches a reply](https://connectbyjbrh.com/docs/memory/memory-in-channels/)
- [Phone and voice in Connect](https://connectbyjbrh.com/docs/phone/)
- [Why the machine proposes a merge and a person disposes](https://connectbyjbrh.com/research/one-person-many-channels/)
- [Relationships in Connect](https://connectbyjbrh.com/docs/relationships/)

## What this page is based on

- docs-source/sources/PHONE.md §3 — the worker's doors and voice.end_call
- docs-source/sources/PHONE.md §9 — deferred finish, NOT_A_CONVERSATION, hangup_by
- docs-source/sources/PHONE.md §10 — name guards, phone_key, identify_caller
- docs-source/sources/PHONE.md §1 — calls and call_events replay protection
