0084 — One Company knowledge base per company: the only store Clara, Settings and ingest use

1. The problem

A company's facts live in three places that disagree: the typed Settings answers and free-form sections on the company and building nodes (ATTACH#setting#knowledge.*), the legacy building record (PROP#/KNOWLEDGE, where Camellia's twelve sections and fee schedule live and the Settings page showed blank on 2026-11-03), and ingest's sheet, which proposes into a page few people open. The Situs application fee reads $45 on the listing, $40 in charges, $48 and $31 in marketing text, "no application fee" from a staff reply, and $45 or $31 on AppFolio's own unit fields, and Clara picked one. Typed forms refuse the way people describe policy; three UIs carry four names for the same thing; the lease package carries a snapshot figure nobody re-reads.

2. The decision

  1. One store. A company's facts are brain.<topic> rows on its company and building nodes in propflowai's table, one free-form sentence per topic with an envelope (where it came from and its original source class, who confirmed it and their role, whether Clara may say it, which readers may see it, the fair-housing stamp, derived numbers), resolved building over company; open questions and suggestions sit on their own row (brain_suggested.<topic>) that Clara never reads. Each topic declares where it may live, how it inherits, its audience, its reader scope, its safety class, its legacy readers and writers, and whether it may be written yet. The product name is Company knowledge base; it is the only name. There is no second copy anywhere: ingest's ROW# keeps evidence (where found, source, seen, agreement, conflicts, attempts) and no fact.
  2. One reader, one writer. Everything renter-facing (Clara's prompt, her pricing and lease tools, the call snapshot, the tour and key-pickup texts, the lease-answers block, the lease package and packet) reads through readBrain; every writer (the Ask tab's tool, the kb grid's doors, the CLI twin, the review and intake forms, document upload, staff teaching, the fee crons, property creation, the ingest rail, the backfill) goes through writeBrainEntry, which runs the private-information gate on every write; the five storage doors refuse any other write to a field a writable topic owns.
  3. Two views, no cards. Customers see and correct the knowledge base through one Settings tab, "Knowledge base · Ask": the existing Ask Clara chat door with two tools (read entries with their sources, as the signed-in user's role may see them; set an entry). A manager's correction (mayConfirmMoney: property manager, org admin, the four team labels of the 2026-08-19 ruling) applies at once with Undo and pins the value; anyone else's is one more source: a fact if nothing disagrees, a question if something does. The private-information gate and the fair-housing screen run on that tool as they run on the teach rail. The Settings pages Fees, Policies (Knowledge & policies), Knowledge, the building editor and the Knowledge-intake routes are deleted in the PR that ships the tab, and are not replaced by cards. Propflow staff see every entry as a row in the grid at kb.propflowai.co (today's ingest app, renamed; same Cloudflare Pages project, custom domain, ingest.propflowai.co redirects, the Access app renamed), whose Value and Status columns read propflowai's rows through the rail and whose teach/answer/promote/hand-off doors write through it; a staffer's edit is confirmed only on behalf of a named customer manager.
  4. Settings keeps only what makes the product act. Who to call and in what order, hours and holidays (typed), modes, calendars, connections, recipients, sender timing, how Clara talks, renewal engine terms, and a typed home for vendor access instructions. The two that are also facts (escalation/on-call, calendar/hours) are pre-filled from the knowledge base while unset; once saved, a later knowledge-base change arrives as a one-tap question; who gets paged never changes without a person. Phones, links and aliases are the property record.
  5. Ingest is the knowledge base's engine. It reads every channel daily and writes through the rail and one function, acceptRule, shared with the fee crons and property creation: the best source we hold wins when nothing we hold for that unit or building disagrees; a disagreement is one question per building in a capped daily list on the brain_digest path, under the mode model (unset is held; a founder sets it per company, and "Live" is what each company is set to at its rollout), recorded on /conversations; staff words and our own read-backs are evidence, never a vote; nothing from a meeting or internal email becomes what Clara says without a person; learned writes from ingest are gated per company by that same path's mode, the one switch on daily learning (no company list in code, no environment flag). Amended 2026-11-05 from propflowai ADR-0156's review: this replaced "Live by default" and "a code list that is deleted at the end"; a code list of company ids fails propflowai's customer-identifier fence, and a merge never turns a feature on at a real company.
  6. Money, under "one source is enough", for Clara and for leases. Clara states a fee as plain fact whenever one source we hold says it and nothing else we hold for that unit or building disagrees (a manager's word, AppFolio's per-unit ApplicationFee/DefaultDeposit where set and non-zero, a listing, the charges ledger, a document, a staff statement that passes the one-off and fair-housing checks). When records for a building disagree, Clara quotes the better figure with where it was seen, inside the fee line and in renter words, for 14 days after the team is asked, then reads it as not on file with the existing silent hand-off. A value a mayConfirmMoney person confirmed (a Propflow administrator only on behalf of a named customer manager; never a machine) is never replaced by a later machine value without a question. There is no re-ask on age. A lease follows the same rule: the package-review approve and the paperwork rungs re-read every money figure at write time and write any uncontested figure whatever its source; a contested figure holds the lease ("not ready", both figures named) until the building's question is answered or a manager picks one on approval; the deposit on the lease is the deposit Clara quotes, from one function; a lease ledger records every figure written and its source.
  7. Numbers for code are derived, never typed. Deposit tiers, fee × applicants, proration, hours for booking, the emergency list are extracted from the sentence by a parser (an LLM only in the background and never for life-safety); an unclear sentence falls to today's safe path. Hours, holidays, the renewal engine and the on-call chain stay typed. The 2026-10-17 "numbers only from typed values" ruling survives for settings keys and is retired for knowledge; the 2026-10-22 "building evidence reaches Clara only after the customer saves" ruling is replaced by acceptRule.
  8. The knowledge base never holds contact data. Every write runs Fede's private-information gate with a mode per writer; four named topics are operational (used for routing, never said) with zero contact data, a narrowing of "knowledge base is public" recorded here on Gera's decision; machine writes redact. Fede's 09-29 fee rule gains one clause (a fee line that carries where it was posted is quoted with that mark) and otherwise stands.
  9. Migration never makes Clara worse. One reader projects the old rows until the backfill; a census of the assembled prompt, tools, snapshot and lease paperwork per building and reader role, attached to every PR from a read-only prod run, must show no unexpected difference; under "one source is enough" the only render change is a contested figure becoming a sourced quote plus a question (Situs: 7 buildings; Yale: 1; Camellia and Western Slope: none); a topic becomes writable only after every reader and every legacy writer moved; the backfill is one additive prod write on Gera's per-step approval; the removal lane finishes in the same effort.
  10. The drive. Building starts when the plan passes its critics: the ADR PRs and the store first; one combined localhost preview of every screen (the Ask tab, the kb.propflowai.co grid, the stripped Settings) is shown to Gera before any UI PR is split; parts are vertical, ≤~300 lines, off origin/main, driven to merge; every prod write and every per-company rollout is Gera's go; Fede is not looped in.

3. What this does not do

4. What this replaces and retires (inventory, per ADR-0004)

5. Signals (SYSTEMS.md)

6. Consequences

One store with one name and two views. A company whose facts lived only on the old building record (Camellia) shows them without a company tier. A listing never silently outranks a manager, and a disagreement between records becomes one question instead of a guess, and holds the lease it would have touched. A lease and a quote come from one value. Customers get one chat instead of three pages; staff keep the grid they already use. Clara's prompt has a ceiling. Nobody fills a form twice, and nobody is asked to confirm what we already pulled. The costs: about 41 small PRs across two repos over several weeks, three prod data moves on Gera's per-step approval (hours, the ingest rows becoming evidence-only, the backfill), AppFolio's per-unit fee fields synced into the mirror, a domain and an Access app renamed, a removal lane that must finish before the effort closes, and one accepted risk under "one source is enough": a lone wrong figure is stated as fact, and may reach a lease, until a second record arrives or a manager corrects it; the weekly lease ledger diff is the net under that.