Knowledge Layer — one clean copy, every channel

The cross-channel architecture for property knowledge: distill each property's messy notes once, store the clean copy in our database, and let voice, SMS, email, and Telegram all drink from it — consistently, with per-channel delivery rules. Requested by Fede 2026-08-28 night: "what I really wanted is a solution to the knowledge bloat on all channels, not just voice, so we are consistent."

2026-08-29 · Proposed — pending Fede's review · builds on the measured results in messy-input-is-on-us and voice-verbosity-report

The principle: bloat is cured at the LAYER, not per channel. Today each channel gets the property's raw, messy knowledge and each fights verbosity alone. Proposed: one automated distillation step owns "messy → clean" for every property; channels differ only in how the clean copy is delivered and how much of it may be said at once. Fix an edge case in the clean copy once — every channel gets the fix.

Messy property notesPropFlow DB · per property
Auto-cleanerAI rewrite · no fact ever dropped
One clean copy per propertystored in our DB
Voice · dedicated agentknowledge slot, loaded up front✓ tested live — fastest
Voice · shared agentkeeps per-call injection⚠ namespacing unsolved
SMS · Email · Telegramclean copy injected per message✓ same mechanism as today

Live data — today’s availability, tour slots, the caller’s own context — is always injected fresh, never stored in a document. Mid-call lookup is rejected: one real call stalled 12 seconds before speaking.

1 · The problem, stated across channels

2 · The layer

StageWhat it isStatus
Source of truthProperty knowledge in OUR database, namespaced by property id — as today. Clients hand us mess; that stays allowed ("messy input is on us").exists
DistillerAn automated AI pass per property: rewrites each block answer-first ("QUICK ANSWER: … / DETAILS if asked: …"), with a deterministic guard that hard-fails if any dollar amount, percentage, or time token is lost. Output stored back in our DB as the property's clean copy, content-hashed. Re-runs whenever the source changes.built & proven (fact-token gate passed on all 8 Willows blocks)
Delivery, per channelSee §3. Channels never re-clean; they only choose what to say.partially measured
Volatile lane (bypasses the layer)Current availability, today's tour slots, the caller's own context — injected live per call/message on every channel, never stored in a document. A clean copy that can go stale by lunchtime is a bug, not knowledge.exists (today's webhook/injection)

3 · Delivery per channel

ChannelHow the clean copy arrivesDelivery budget (how much may be said)Evidence
Voice — dedicated agent per property (Willows-style fleet)Platform knowledge slot, full doc loaded up front, CI-synced with content-hash naming + read-back verification. No mid-call lookup (retrieval measured a 12s tail stall — rejected).Spoken: lead with the asked fact, one dollar amount and one date, offer to text the rest.Fastest arm on real calls: first word 1.47s med / 1.84s p90, beats today. Instructions −16.7%.
Voice — shared agent (Camellia + Yale on one agent today)UNCHANGED: per-call webhook injection keyed by the number dialed — a static per-agent doc cannot tell these callers apart. They still benefit from the layer: the injection sends the CLEAN copy instead of the raw one.Same spoken budget.Namespacing on shared agents untested — the gate that moved the voice pick from A to B.
SMSPer-message injection into the drafting context (as today), clean copy instead of raw.Short: answer + one figure; link/offer the breakdown.Injection path validated end-to-end 2026-08-28 (137-conversation replay).
EmailSame per-message injection, clean copy.Full breakdown allowed — email IS the "send me the details" destination every other channel offers.Same replay validation.
Telegram / chatSame per-message injection, clean copy.SMS-like budget.Shares the drafting tier; no separate measurement yet.

4 · Namespacing, spelled out

5 · Sync & failure honesty

6 · What this does NOT solve — said plainly

The rambling itself. Words-per-reply were flat across every measured setup: the model recites whatever details it can see, clean or messy. The cure is the answer-behavior dial (the spoken-delivery budget enforced per channel), iterated on the existing harness with the conciseness contracts. The layer makes that dial consistent and cheap to iterate; it does not replace it.

7 · Decision — pick one

OptionWhat happensTrade
A · RecommendedAdopt the layer, channel-by-channel behind gatesDistiller becomes a first-class pipeline stage writing clean copies to our DB. Text channels switch injection to the clean copy first (lowest risk — same mechanism, better content, one replay-harness pass as the gate). Voice dedicated-agents adopt the knowledge slot behind the round's gates (leakage test, bigger sample). Shared voice agents keep injection until the dedicate-vs-share decision.Several gated steps instead of one launch; nothing big-bang.
BLayer yes, voice-slot noAdopt distiller + clean-copy injection on ALL channels including voice (shared mechanism everywhere); skip the platform knowledge slot entirely.Maximum consistency, one delivery mechanism; forgoes the measured first-word speedup and the −16.7% prompt cut on dedicated agents.
CHold everythingKeep raw blocks everywhere; revisit after the rambling dial ships.Bloat and inconsistency persist on every channel; the dial fights messy content.

Sequencing note under A: the dedicate-an-agent-per-property question (which unlocks the voice slot for Camellia/Yale) is its own decision with fleet-management costs — it should ride the existing config-as-code sync, and nothing above depends on answering it first.

8 · Provenance

Measurements: live TTFW round + nine-arm simulate matrix, 2026-08-28 (voice-verbosity-report §8c–8d); text-pipeline replay validation (effort-replay-validation-2026-08-28); industry research and distiller POC by the parallel session (messy-input-is-on-us). Verified platform facts: per-agent attachment lists, indexing requirement, platform-settings non-inheritance, override-permission gating — all read from live configs 2026-08-28. Author: Claude (Fede's session), same-night synthesis of both sessions' work.

PropFlow Docs