processync
Open for new work
CASE 07·FINANCIAL SERVICES · 4,200 EMPLOYEES

An agent that remembers who it is talking to, and who it works for.

We built a knowledge agent with three separate memory levels (user, team, and organisation) so answers stay personal without going private, and stay canonical without going stale. It runs on OpenSearch and a graph store, and people reach it by tagging @sync in Slack or Teams. Discovery in week 1. Production in week 8.

MAYA ELLROY · PRINCIPAL ENGINEER2026-07-2911 MIN READENGAGEMENT · PRX-SPR · 8 WEEKS
Repeat questions
-62
%
Fewer duplicate questions reaching the internal help desk, weeks 5-12.
Answer latency
1.4
S P95
Three-level retrieval fan-out, including ACL filtering.
Memory records
4,100
Live at handoff. 218 canonical, 1,340 team, the rest personal.
Weeks to production
8
Fixed scope, fixed window, signed handoff on day 56.
01 · The problem

Their first agent had perfect recall and no memory.

The client had already shipped a retrieval assistant over 1.2M documents. It could quote the credit policy verbatim. It could not remember that the analyst asking had requested the EMEA variant four times that month, that her team had agreed in April to stop citing the deprecated 2023 memo, or that Legal had since replaced the policy outright.

Every session started from zero. So people re-explained their context, re-corrected the same mistakes, and eventually stopped asking. Usage fell 40% in the second quarter after launch.

The instinct was to give the agent one big memory store. We argued against it. A single store forces one answer to two incompatible questions: what is true for you, and what is true for the company. Those need different write rules, different lifetimes, and different blast radius.

02 · Three levels of memory

One agent. Three memories. Different rules for each.

Scope determines who can write, how long a record lives, and how loudly it speaks at retrieval time.

LEVEL 1PRIVATE

User memory

Working context for one person: their region, their reporting line, the format they want, the corrections they made last week. Written automatically, visible only to them, never cited to anyone else.

WRITE  Agent, automatic
TTL    Rolling 90 days
READ   Owner only
LEVEL 2WORKSPACE

Team memory

The decisions and vocabulary a group operates on: which vendor was chosen, what "tier 2 exposure" means here, the runbook for month-end close. Promoted from user memory when two or more members confirm it.

WRITE  Promotion, 2 confirmations
TTL    Review at 180 days
READ   Team scope
LEVEL 3CANONICAL

Organisational memory

What the company will stand behind: policy, approved answers, product truth, named owners. Every record is versioned, has an accountable human, and supersedes lower levels on conflict.

WRITE  Human approval only
TTL    None, versioned
READ   Org-wide, ACL filtered

The rule the whole system rests on: memory moves up, never sideways. Nothing enters team memory without confirmation, and nothing enters organisational memory without a name attached to it.

03 · The write path

Capture is cheap. Promotion is expensive on purpose.

The agent proposes memory constantly and commits it rarely. Five stages sit between a sentence in a conversation and a record the company vouches for.

W1
Extract candidates

After each turn, a cheap model pulls durable statements out of the transcript and drops anything time-bound or task-local.

W2
Deduplicate against all three levels

If organisational memory already says it, the candidate is dropped. If it contradicts, it becomes a conflict ticket rather than a record.

W3
Classify scope

Personal preference, team convention, or company fact. Ambiguous cases default down to the narrowest scope. The cost of a wrong personal memory is one annoyed user, not 4,200.

W4
Queue for promotion

A record seen by 2+ people in a team surfaces in that team's weekly digest as a one-click promote or reject. 71% of promotions happened from the digest, not the console.

W5
Ratify to canonical

Only a named owner in the knowledge council can write level 3, and every write produces a new version with a diff. No silent edits to company truth.

04 · The read path

Every answer says which memory it came from.

Retrieval fans out across all three levels in parallel, filters by the caller's ACLs before ranking, then reranks with a scope weight: canonical outranks team, team outranks personal, and a personal preference can change the shape of an answer but never its facts.

The agent then shows its sources by level. Users trusted the system roughly a week after we shipped that label. Being able to see why it knew something mattered more than the answer quality gains.

Underneath, this is a RAG system with two stores rather than one. OpenSearch holds the enterprise corpus and every memory record, with BM25 and vector search in a single hybrid query. A graph database holds the relationships OpenSearch cannot express: which team owns which policy, which record supersedes which, who confirmed what, and how a person sits in the org. Retrieval walks the graph to decide what is in scope, then asks OpenSearch for the text.

OpenSearch

1.2M documents plus 4,100 memory records. Hybrid BM25 + kNN, scope and ACL as filter clauses so nothing unauthorised reaches the reranker.

Graph store

People, teams, systems, policies, and memory records as nodes. Edges carry OWNS, SUPERSEDES, CONFIRMED_BY, MEMBER_OF.

Orchestrator

Resolves the caller, fans out across the three memory levels, reranks with scope weighting, and writes the answer trace. One service, four engineers own it.

Answer trace · analyst query, EMEA exposure limits
ORG · v4Tier 2 exposure ceiling is 8% of book value. Owner: Risk · ratified 2026-06-02.
TEAM · EMEADo not cite the 2023 exposure memo. Superseded, agreed 2026-04-11.
USERPrefers figures in EUR, table first, prose second.
05 · Where people use it

Nobody opens a knowledge tool. They tag the agent in Slack.

The console exists for governance. The actual surface is Slack: mention @sync in any channel or DM and the agent answers in thread, resolving your identity from your Slack user, your team memory from the channel, and canonical memory from the org.

The same agent runs in Microsoft Teams. One bot service, two adapters: Slack Events API and the Bot Framework. Identity resolves from Slack user or Entra ID to the same graph node, and a Teams channel binds to a team memory scope exactly as a Slack channel does. Their compliance group required Teams for the regulated business units, so both run side by side against one memory layer.

Channel context does real work. The same question asked in #emea-risk and #us-risk returns different team conventions over the same canonical policy. Answers in a channel are also the cheapest promotion signal we have. A thumbs-up from a second team member is one of the two confirmations a team memory needs.

SAME AGENT · SAME MEMORY
# emea-risk24 MEMBERS09:41
AL
Anna Lindqvist09:41

@sync what's our tier 2 exposure ceiling, and does the 2023 memo still apply?

syncAPP09:41

8% of book value. The 2023 memo is superseded. Your team agreed on 2026-04-11 to stop citing it, and Risk ratified the replacement in June. Figures below in EUR, table first, as you prefer.

ORG v4 · exposure policy · Risk
TEAM · #emea-risk convention
USER · EUR, table first
↑ 2SAVE TO TEAM MEMORY1 more confirmation needed
SLACK EVENTS API · SCOPE FROM CHANNEL ID · /sync ASK2 replies in thread
Identity

Slack user or Entra ID maps to the same graph node, so ACLs and personal memory resolve without a second login.

Channel as scope

Every Slack channel and Teams channel is bound to a team memory scope. DMs fall back to personal plus canonical only.

Promotion in place

Reactions and the save action are confirmations. Governance happens where the conversation already is.

Adoption

83% of queries at handoff arrived through a chat surface: 61% Slack, 22% Teams. The console saw 40 users, all of them owners.

06 · What we got wrong

Two corrections, both in week 4.

Correction 1

We let the agent promote to team memory on a single confirmation. Within days, one manager's private assumption about approval thresholds was being quoted to her whole department as team convention. Two confirmations, plus a visible provenance line, fixed it.

Correction 2

Our first TTLs deleted stale memory silently. People noticed the agent getting dumber and couldn't say why. Expiry now archives rather than deletes, and the weekly digest lists what lapsed.

Appendix · Record shape

One schema across all three levels. Scope, owner, and provenance are mandatory fields, and that is what makes governance possible without a second system.

{
  "id":         "mem_9f4c21",
  "scope":      "team",            // user | team | org
  "scope_id":   "team_emea_risk",
  "claim":      "Do not cite the 2023 exposure memo.",
  "provenance": ["conv_8812", "conv_9043"],
  "confirmed":  ["u_214", "u_377"],
  "owner":      "u_214",
  "supersedes": "mem_71ab08",
  "version":    2,
  "expires":    "2026-10-11",      // null when scope = org
  "acl":        ["grp_emea_risk"]
}
07 · Exit

Handoff signed on day 56.

Their four engineers ran the promotion queue on their own from week 6. We left the memory service, the digest job, the governance console, and a written runbook for the knowledge council. No retainer, no dependency.