← Decision hub All research All sources

Current state audit

LTA current workflow and data shape audit

How listing descriptions, photo captions, guest messaging, and current data flows match the approved model, including what to reuse, wrap, generalize, retire, and build.

21 minute read 0 original links Confidence: High
Founder takeawayDo not greenfield. Preserve the proven fact and audit machinery while replacing fragmented storage and vendor identity assumptions.
Open original source links (0)

    No external links were extracted from this document.

Date: 2026-07-10
Scope: Lake Tahoe Accommodations listing descriptions, photo captions, Conduit guest messaging, Roam Free HostBuddy-era profiles, onboarding, and the shared property-data substrate.
Method: read-only repository audit. No production code, schema, credentials, or client data changed.

Executive verdict#

The proposed immutable raw history → vendor-neutral canonical operating model → derived intelligence and accelerators architecture is directionally correct, and this repository has already proved much of it in working code.

The important conclusion is not “reuse the current system.” It is:

Preserve the proven mechanics, replace the tenant-specific data contract.

The strongest existing assets are the immutable LTA Bronze archive, generic fact reconciliation and publish gates, deterministic claim dossiers, human approval ledgers, fail-closed write guards, readback verification, and content provenance. Rewriting those would waste working code and reintroduce solved failure modes.

The current data shape is not the wide base for the new company, however:

  • LTA is a logical tenant inside one shared Supabase project, while the newly locked premium architecture requires a separate client data plane.
  • Raw storage is a Tahoe-specific table with a hard-coded source enum and a property-code join, not a generic connector/object history.
  • “Canonical” property information is split across properties columns, atomic_property_facts, properties.amenities, properties.metadata, child-entity facts, and legacy questionnaire/Notion projections.
  • Source authority is mostly encoded in Python precedence tuples and workflow documents, not in a client-visible, per-field authority registry with effective dates and conflict rules.
  • Property identity is partly vendor-neutral (properties.id) but many LTA workflows still key state and joins on unit_code, marketing_code, Streamline home_id, or Conduit entity IDs.
  • Derived content is governed well, but its version history is inconsistent: caption drafts and write receipts are durable; full LTA listing-copy versions still depend heavily on local JSON paths and Notion staging.
  • The HostBuddy-era manual profile builder guesses missing operational facts and places AI-DRAFTED material in a runtime knowledge page. That behavior conflicts with a first-principles safety model and should not carry forward.
  • The Roam Free Conduit renderer deliberately emits secrets such as Wi-Fi passwords in full to Conduit. That conflicts with the new promise that sensitive data can remain local and never reach frontier or external AI systems.

Overall shape match:

  • Raw history: strong prototype, not generic
  • Canonical model: partial and fragmented
  • Derived intelligence/accelerators: strong, but content-first and tenant-specific
  • Vendor portability: partial
  • Separate premium client data planes: not matched
  • Safe client/agent extensibility: not yet a platform contract

Current-state component and data-flow map#

flowchart TD
    S[Streamline admin and public listing] --> B[tahoe_source_snapshots Bronze]
    BW[Breezeway exports and guidebook] --> B
    N[Notion property and working files] --> B
    P[Gallery URLs and PM captions] --> B
    O[Owner attestations] --> B

    B --> F[parse, normalize, reconcile, certify]
    F --> C[atomic_property_facts]
    F --> K[knowledge_conflicts]
    F --> E[atomic child entities and facts]

    C --> G[listing gather brief]
    E --> G
    S --> G
    P --> G
    G --> D[property listing dossier]
    D --> A[listing authoring and adversarial review]
    A --> LR[lta_listing_runs and local copy JSON]
    LR --> W[gated Streamline writers]
    W --> V[readback verification and receipts]
    W --> CS[Conduit PMS resync]
    CS --> CV[Conduit sync verification receipt]

    P --> CB[gallery baselines and frame observations]
    D --> CD[per-photo caption dossier]
    CB --> CD
    CD --> CR[lta_caption_drafts and review ledger]
    CR --> GW[gated gallery writer]
    GW --> GR[per-photo push receipts and readback]

    OR[OwnerRez and onboarding inputs] --> R[CanonicalRecord read model]
    C --> R
    R --> GE[GuestExport and TeamExport]
    GE --> HN[HostBuddy-era Notion guest profile]
    GE --> CO[Conduit overlay renderer]

LTA listing descriptions#

  1. Source captures land in tahoe_source_snapshots, an append-only table protected against update, delete, and truncate. Evidence: supabase/migrations/20260620120000_tahoe_trustworthy_pipeline.sql.
  2. Generic fact code parses source claims into {property_code, key, value, source, quote, snapshot_id, value_type}, detects cross-source conflicts, chooses a winning source, and writes governed facts plus provenance. Evidence: lib/facts/model.py, lib/facts/reconcile.py, lib/facts/persist.py, lib/facts/publish.py.
  3. Tahoe-specific policy binds the generic engine to a workspace, source list, join key, source precedence, aliases, and publish criteria. Evidence: lib/facts/profiles/tahoe.py, lib/tahoe_facts/*.py.
  4. scripts/tahoe-listing-gather.py builds a writer brief from confirmed canonical facts, governed child facts, Streamline Bronze, the public scrape, PM captions, frame observations, proximity, and review signals. It hard-redacts credentials and team data.
  5. lib/property_listing_dossier.py converts that heterogeneous brief into a deterministic allowlist: allowed_claims, do_not_claim, review flags, missing inputs, readiness, source hash, and parameter hash. An adversary verdict can fail the dossier closed.
  6. Human/AI authoring follows the LTA template and rubric in skills/tahoe-listing-writeback/references/. The assembler refuses claims that cannot trace to the dossier and emits exact Streamline Desc and Airbnb payloads.
  7. lta_listing_runs records pipeline state and artifact paths. The Streamline writers are dry-run by default, require a reviewed approval manifest, take backups, write one property, and verify readback. Evidence: lib/lta_listing_runs.py, scripts/streamline-listing-writer.py, scripts/tahoe-listing-assemble.py.
  8. Conduit receives the live description indirectly from its Streamline PMS connection. Because there is no API to trigger that refresh, a human triggers it and scripts/tahoe-conduit-sync-verify.py proves the expected description reached the LTA workspace before the run is considered complete.

LTA photo captions#

  1. Streamline gallery baselines pin image_id, position, filename, PM title, current caption, and image URL. Photo bytes can be archived by immutable byte hash in Supabase Storage. Evidence: docs/tahoe-pipeline/CAPTION-PUSH-PHASE2-PLAN.md, supabase/migrations/20260706210000_gallery_photos_archive.sql.
  2. A separate observer records per-frame space, co-visible spaces, seating, and visible features. The property dossier and frame facts are projected into a per-photo allowlist by lib/lta_caption_dossier.py.
  3. The authoring output is structurally narrow: {kind, code, home_id, generation_baseline_id, writer_model, captions:[{image_id,draft_caption}]}. Titles cannot be drafted because the schema has no title field. Evidence: lib/lta_caption_author.py.
  4. lta_caption_drafts is the durable draft and approval ledger. Draft ingest cannot set approval fields; human approval cannot overwrite draft provenance. writer_model is stored per caption.
  5. lta_caption_reviews snapshots what the reviewer saw and their decisions. lta_caption_push_receipts records per-photo before, after, approver, write time, verification, and approval token. Evidence: migrations 20260705150000, 20260707120000, and 20260707140000.
  6. Live writes are canary-first, per-property approved, fresh-baseline checked, one-shot, and readback verified.

Guest messaging and property profiles#

There are two generations of guest-knowledge handling.

HostBuddy-era manual model

  • skills/hostbuddy-profile/SKILL.core.md builds a 28-section Notion page from listing/onboarding notes plus reusable blocks stored in hostbuddy_canonical_sections, hostbuddy_standard_blocks, and hostbuddy_appliances.
  • HostBuddy reads the Notion page body verbatim.
  • Missing facts are guessed and marked AI-DRAFTED; verified standard blocks are pasted verbatim.
  • lib/onboarding_intake/views/guest_profile_md.py and guest_profile_blocks.py later made the rendering deterministic and reusable.
  • lib/guest_profile_publisher.py publishes the rendered page behind an explicit force flag.

Conduit-era model

  • LTA currently relies on Conduit's Streamline PMS sync for listing descriptions and structured PMS knowledge. The repository verifies sync but does not directly overwrite those PMS-owned nodes.
  • Roam Free has a separate custom-overlay path: CanonicalRecord -> GuestExport -> conduit_renderer -> conduit-kb-push.py.
  • conduit_kb_nodes mirrors Conduit nodes; conduit_pushed_nodes is an idempotency ledger for custom nodes the system owns.
  • The client is correctly workspace-token scoped and refuses to patch PMS-owned nodes. Evidence: lib/conduit_client.py, lib/conduit_renderer.py, scripts/conduit-kb-pull.py, scripts/conduit-kb-push.py.

Concrete schema inventory#

Raw/source layer#

Shape Current use Key fields Audit verdict
tahoe_source_snapshots Immutable LTA source payloads workspace_id, property_code, source, source_url, fetched_at, content_hash, payload, metadata Strong immutability and replay; Tahoe-specific, source CHECK requires migrations, uniqueness omits workspace
tahoe_reviews_snapshots Reva guest-review Bronze source payload plus metadata Correctly separated from property-fact rebuild; source-specific table proliferation
tahoe_gallery_baselines / photos Gallery metadata snapshots baseline ID/hash, image ID, position, title, caption, URL Good point-in-time evidence; external table lineage is partly outside this migration chain
gallery_photo_objects Canonical photo bytes client/property code, image ID, SHA-256, storage path, source URL Strong reorder-immune byte identity; client_code is not a tenant FK and bucket is public by design
conduit_kb_nodes Current Conduit mirror Conduit node ID, workspace/property IDs, title/body, parent, entity IDs, source, metadata Useful connector mirror, but mutable current state rather than immutable raw history
Breezeway/Streamline landing tables Source-specific caches vendor IDs, property code, operator notes Useful adapters, not the permanent model

Canonical/governance layer#

Shape Grain Important fields Audit verdict
properties one property UUID, workspace, display/core fields, amenities JSONB, metadata JSONB, vendor columns UUID is a good permanent identity seed; too many facts still live outside governed atoms
atomic_property_facts one chosen value per property/key property/workspace, key, string value/type, source, confidence, status, endpoint class, verifier, meta provenance Strong governed fact envelope; cannot retain multiple live candidates, source authority is not data-driven
atomic_property_entities stable room/bed/bath/proximity entity UUID, parent property/entity, type, key, status, source, confidence, meta Correct solution for repeated grains; entity keys are parser-stable rather than vendor IDs
atomic_property_entity_facts one chosen value per entity/key value/type/source/status/endpoint/provenance Strong extension of atomic governance
knowledge_conflicts one detected disagreement property/code/workspace, field, severity, source-values/evidence JSON, chosen value/source Source-agnostic conflict payload is reusable; lifecycle/authority policy needs generalization
onboarding_field_catalog plus Python registry field definitions and intake behavior key, type, endpoint class, capture route, required/review rules Valuable ontology seed; code and DB catalog need one authoritative contract
CanonicalRecord in-memory property projection core, fact rows, amenities, metadata Effective adapter for legacy split storage; the split itself should not be the target model

Derived/output layer#

Shape Grain Important fields Audit verdict
property_listing_dossiers versioned property/purpose/source hash dossier JSON, allowed/denied claims, readiness, hashes, source artifacts Excellent reproducible accelerator boundary; reusable with a generic tenant/purpose key
lta_listing_runs one LTA unit stage, gates, artifact paths, URLs, shipped flag Good state-machine pattern; globally unique unit code and local artifact paths are not portable
listing_versions property/channel/version copy fields, status, generation/approval/publication Useful earlier generic concept, but LTA workflow does not use it as its durable full-copy ledger
lta_caption_runs one LTA unit stage, baseline IDs, approval, artifacts Strong workflow state, but tenant-specific and code-keyed
lta_caption_drafts one photo/run baseline/draft/approved caption, reviewer, writer model Strong durable content/version/provenance pattern
lta_caption_reviews one review emission exact rows shown, decisions, approver Reusable human-approval evidence pattern
lta_caption_push_receipts one written photo before/after, approval, write/verify details Reusable publication receipt pattern
lta_listing_edits one surgical edit invocation reason, changes, editor, optional push receipt Good audit pattern but not a substitute for full listing-version history
conduit_pushed_nodes property/overlay key Conduit node ID, content hash, status Good idempotency ledger; needs tenant/source-connection keys
HostBuddy Notion profile one page/property 28 section body Human-friendly presentation, not canonical storage

Shape-match matrix against the proposed architecture#

Proposed requirement Current evidence Match Required change
Immutable raw source history Append-only tahoe_source_snapshots with content hashes and mutation triggers High for LTA Generalize to tenant/connection/object/version; keep source adapters out of core schema
Vendor-neutral permanent IDs properties.id, child entity UUIDs; vendor IDs carried separately Medium Make tenant-owned resource ID the only internal FK; move every vendor key into external-identity mappings
Explicit source authority/conflict rules Tahoe precedence tuple, endpoint classes, conflict ledger, human attestations Medium-low Store authority by tenant + entity type + field + context + effective dates; no silent code-only precedence
Canonical operating model Atomic facts and entities exist Medium Collapse the four-home logical model into governed facts/entities behind compatibility views
Derived intelligence and accelerators Dossiers, listing/caption workflows, review signals, Conduit overlays High Re-key as generic content/intelligence artifacts and keep client-specific recipes as configuration
Separate premium client data plane Shared Supabase plus workspace_id and RLS Low Deploy the reusable schema/runtime per premium client; shared control plane may hold non-client operational metadata only
Data view/export/transform RPCs and export views exist; many outputs are service-role-only Medium-low Add client-scoped export APIs, bulk snapshots, schemas, lineage, and change streams
Client/agent extensibility Conduit API client and webhooks exist in places Low Publish stable read APIs, scoped webhooks, event contracts, service accounts, and policy-enforced agent tools
Safe local/private AI Secret walls exist on some paths Low Add data classification and execution policy before model calls; support local-model routes and redact/tokenize external routes
Vendor migration/repointing Canonical facts are partly independent; writers are vendor-specific adapters Medium Formalize connector contracts and external-ID mapping; build export/import reconciliation, not PMS-to-PMS transformations

Reusable code inventory#

REUSE AS-IS#

These are pure or narrowly infrastructural components whose behavior already matches the target principles:

  • lib/facts/model.py: candidate fact and conflict envelopes.
  • lib/facts/reconcile.py: deterministic, source-agnostic conflict detection.
  • lib/facts/persist.py: offline write plans and explicit flush seam.
  • lib/facts/publish.py: evidence-based fail-closed promotion.
  • lib/property_listing_claim_contract.py and lib/listing_claim_trace.py: claim licensing and trace patterns.
  • lib/property_listing_dossier_adversary.py and lib/lta_caption_dossier_adversary.py: independent refutation pattern.
  • lib/streamline_write_guard.py: approval-manifest, drift, and scoped-write guards.
  • lib/conduit_client.py: bounded API client, pagination, workspace-specific credentials, and PMS-node protection.
  • Caption approval separation in lib/lta_caption_runs.py: draft ingest cannot set approval; approval cannot rewrite draft provenance.
  • Immutable content hashing and replay conventions in the dossier and Bronze code.

“Reuse as-is” means keep behavior and tests. It does not mean keep Tahoe table names forever.

EXTRACT / GENERALIZE#

  • lib/facts/profile.py and lib/facts/profiles/tahoe.py: retain the profile mechanism, but move source authority from a single precedence tuple to policy records.
  • lib/property_listing_dossier.py: make tenant_id, resource_id, artifact_type, and policy_version first-class; retain hashes and allowlists.
  • lib/lta_caption_dossier.py: retain per-media projection; remove LTA naming and store the dossier as a versioned content artifact, not inside a run JSON blob.
  • lib/lta_listing_runs.py and lib/lta_caption_runs.py: extract one generic workflow-run engine with typed stages, gates, artifacts, approvals, and receipts.
  • lib/onboarding_intake/field_registry.py: use as the ontology seed, but generate Python types and UI catalogs from one versioned schema contract.
  • lib/onboarding_intake/views/record.py: preserve as a compatibility adapter while migrating away from split canonical storage.
  • lib/onboarding_intake/views/notion_exports.py: preserve classification and audience-wall logic, but turn the output into a vendor-neutral knowledge-pack projection.
  • gallery_photo_objects: generalize client_code/property_code to tenant/resource IDs while retaining hash-based immutable object identity.

WRAP WITH ADAPTER#

These components should remain vendor-specific at the edge:

  • Streamline capture, description writer, Airbnb writer, gallery scraper/writer.
  • OwnerRez sync, listing writer, and webhook code.
  • Conduit pull, push, PMS-sync verification, and entity mapping.
  • Notion property-profile and working-file publishers.
  • Breezeway exports and guidebook parsers.
  • Reva review ingestion.
  • PriceLabs, RevA, Slack, and future connectors.

Each adapter should implement the same core contract: capture raw, map external identity, emit candidates/events, read current state, plan write, execute approved write, verify, and emit receipt.

RETIRE / DO NOT CARRY FORWARD#

  • The HostBuddy manual rule “guess anything missing and mark it AI-DRAFTED” in skills/hostbuddy-profile/SKILL.core.md. Unknown operational facts must remain unknown, block unsafe answers, or route to a human.
  • Any runtime knowledge page as a source of truth. Notion and Conduit are editable/presentation/runtime consumers, not canonical stores.
  • prompts/listing-description-airbnb-channel.md for current LTA generation; it is already marked legacy and conflicts with the master-description split.
  • The older generic Streamline prompt when it conflicts with the HCH0868 contract. There should be one versioned recipe per artifact, not several “canonical” prompt files.
  • Direct reliance on local artifact paths as durable evidence. A path may be a cache pointer, never the only copy of approved content.
  • Global uniqueness on unit_code or property_code without tenant/resource scope.
  • Direct external-AI delivery of unredacted secrets from lib/conduit_renderer.py. Secrets need a policy-controlled retrieval tool or local execution path.
  • Vendor enum growth in the core raw table. Adding a connector should not require widening a CHECK constraint.

MISSING / NEW BUILD#

  • Generic connector, raw object, raw event, and sync-run schema.
  • Permanent external-identity mapping table.
  • Field/source authority registry with conflict rules and effective dates.
  • Candidate-value store that retains all current source claims outside raw blobs.
  • Generic canonical-decision ledger linking chosen values to candidates/evidence and approval.
  • Generic content artifact/version/review/publication model covering descriptions, captions, reports, social posts, websites, and agent knowledge packs.
  • Data classification and execution-policy engine for model/tool access.
  • Client export API, scoped service accounts, webhooks, and schema/version discovery.
  • Per-client data-plane deployment and backup/restore automation.
  • Migration/repointing toolkit with source/destination diff and reconciliation receipts.

Duplication, drift, and collision risks#

1. The same property fact exists in many shapes#

A fact such as occupancy, parking, Wi-Fi, pet policy, hot tub, or check-in instructions can appear in:

  • Streamline structured fields
  • Streamline listing prose
  • Streamline photo captions
  • Breezeway property notes or guidebook
  • properties columns
  • atomic_property_facts
  • properties.amenities
  • properties.metadata.owner_sops
  • property_questionnaire
  • HostBuddy/Notion page body
  • Conduit PMS nodes
  • Conduit custom overlay nodes
  • listing dossier JSON
  • caption dossier JSON
  • generated listing/caption copy
  • local staging files

The current code often handles this defensively, but the duplication remains. The new platform should distinguish source claims, canonical decisions, and published projections so users never wonder which copy to edit.

2. “Canonical” is physically split#

CanonicalRecord proves the problem: it must merge core, facts, amenities, and metadata, and its value_for method imposes a facts-over-core-over-amenities lookup order. That is a compatibility rule, not field authority. Continue supporting the adapter, but stop adding new canonical homes.

3. Source precedence is too coarse#

lib/facts/profiles/tahoe.py ranks entire sources. Real authority is field- and context-specific. Streamline may own reservation status, while a human-attested guidebook owns parking instructions, PriceLabs owns a recommendation but not the accepted rate, and Conduit owns message events but not property facts. A single precedence tuple cannot express this.

4. The Notion round trip can create echoes#

The Guest Profile is rendered to Notion, then questionnaire tooling can parse the page back into property_questionnaire, and compatibility code can synthesize q_* facts. The code contains deduplication and dual-read fallbacks because echoes already exist. The new design should make projections explicitly non-ingestible unless a user edits a governed field through a defined command.

5. LTA run keys are not tenant-safe platform IDs#

Several LTA tables use globally unique unit_code; dossiers use client_code + property_code; Bronze uniqueness omits workspace. This is acceptable for a bounded engagement, not a wide platform. Every row should carry tenant ID plus permanent resource ID; external codes belong in a mapping table.

6. Logical tenancy conflicts with the locked premium architecture#

The shared Supabase workspace/RLS work is competent, but it is the future low-cost multi-tenant pattern, not the premium client data plane. LTA data currently shares infrastructure with Roam Free. The target should reuse schema and code, not the same database/storage/secrets boundary.

7. Guest-messaging secret handling is inconsistent#

Notion exports redact Wi-Fi passwords by default, while the Conduit renderer explicitly disables redaction and delegates disclosure controls to Conduit. That is incompatible with the local/private AI promise. A secret should remain in a classified vault and be retrieved only for an authorized reservation/person/purpose, preferably without entering an LLM prompt.

8. Listing version durability trails caption durability#

Caption history is reconstructable from Supabase. Full LTA description versions are not equivalently centralized: runs store paths, Notion holds staging pages, and edits hold deltas. Introduce a full content-version ledger before scaling the pattern to social, website, compliance, and bookkeeping outputs.

9. Current-source mirrors are mistaken for raw history in places#

conduit_kb_nodes is an upserted mirror, not immutable history. The same distinction will matter for Slack, PriceLabs, RevA, and Streamline operational objects. Keep “latest mirror” for convenience, but derive it from immutable captures/events.

erDiagram
    TENANT ||--o{ DATA_PLANE : owns
    TENANT ||--o{ RESOURCE : owns
    RESOURCE ||--o{ EXTERNAL_IDENTITY : maps_to
    SOURCE_CONNECTION ||--o{ RAW_OBJECT_VERSION : captures
    SOURCE_CONNECTION ||--o{ SYNC_RUN : executes
    RESOURCE ||--o{ FACT_CANDIDATE : receives
    FACT_DEFINITION ||--o{ FACT_CANDIDATE : types
    RAW_OBJECT_VERSION ||--o{ FACT_CANDIDATE : evidences
    RESOURCE ||--o{ CANONICAL_DECISION : has
    FACT_DEFINITION ||--o{ CANONICAL_DECISION : defines
    FACT_CANDIDATE ||--o{ CANONICAL_DECISION : supports
    CANONICAL_DECISION ||--o{ CONFLICT : resolves
    RESOURCE ||--o{ CONTENT_ARTIFACT : produces
    CONTENT_ARTIFACT ||--o{ CONTENT_VERSION : versions
    CONTENT_VERSION ||--o{ APPROVAL : reviewed_by
    CONTENT_VERSION ||--o{ PUBLICATION_RECEIPT : delivered_as
    RESOURCE ||--o{ MEDIA_ASSET : owns
    MEDIA_ASSET ||--o{ MEDIA_PLACEMENT : appears_as
    TENANT ||--o{ AGENT_POLICY : governs

Recommended definitions:

  • Tenant: client legal/operating boundary.
  • Data plane: the client's database, storage, secrets, queues, workers, backups, and optional local-model runtime.
  • Resource: permanent client-owned object such as property, owner, guest, reservation, conversation, task, vendor, account, document, or media asset.
  • External identity: {resource_id, connection_id, external_type, external_id, valid_from, valid_to}. Vendor IDs never become internal identity.
  • Raw object version: immutable source response/event with tenant, connection, external object, capture time, source-effective time, schema version, hash, payload location, and classification.
  • Fact definition: canonical key, entity type, data type, units, sensitivity, audience, freshness SLA, validation, and allowed uses.
  • Fact candidate: one source's claim, linked to raw evidence, with observed/effective time and parser version.
  • Canonical decision: chosen value plus explicit policy/approver, candidate links, validity range, and supersession. No last-write-wins.
  • Conflict: competing candidates, severity, status, owner, resolution, and downstream impact.
  • Content artifact/version: descriptions, captions, knowledge packs, reports, social posts, website pages, compliance packets, and bookkeeping workpapers, all versioned against a canonical snapshot and recipe/model version.
  • Approval: who approved what exact hash, for which use and scope.
  • Publication receipt: destination, external identity, before/after hashes, execution result, readback, and rollback pointer.
  • Agent policy: data classes, permitted models/tools, local-only rules, human approval requirements, budgets, and kill switch.

Migration and wrapping plan without rewrites#

Phase 0: freeze contracts, do not move data#

  • Treat current LTA and Roam Free workflows as acceptance fixtures.
  • Preserve the existing tests around facts, dossiers, claims, write gates, caption approvals, and Conduit sync.
  • Record current table/API contracts and mark every current source as canonical, mirror, projection, or scratch.

Phase 1: introduce generic interfaces around existing code#

  • Define adapter protocols for capture, identity mapping, candidate extraction, write planning, execution, and verification.
  • Make current Streamline, OwnerRez, Breezeway, Conduit, Notion, and Reva modules implement those protocols through thin wrappers.
  • Do not change their live behavior.

Phase 2: add the permanent identity and authority layer#

  • Seed permanent resource IDs from the existing properties.id values where safe.
  • Populate external identities from Streamline home IDs, OwnerRez property IDs, LTA unit codes, Breezeway IDs, and Conduit entity IDs.
  • Add a field authority registry and import the current Tahoe precedence as an explicit initial policy, then refine field by field.

Phase 3: shadow the generic raw/candidate/decision model#

  • On each current capture, write the existing Bronze row and a new generic raw-object version.
  • Parse candidates through the existing generic lib/facts engine and compare candidate/conflict/canonical outputs with current tables.
  • No consumer repoint until diffs are explained and accepted.

Phase 4: unify derived content history#

  • Persist every listing description and caption as generic content versions while continuing to feed current LTA tables.
  • Import existing caption ledgers and listing dossiers by hash without rewriting the copy.
  • Use current approval manifests and write receipts as the first implementation of generic approvals/publications.

Phase 5: repoint one consumer at a time#

Recommended order:

  1. Read-only dashboard and exports
  2. Listing dossier reads
  3. Caption dossier reads
  4. Conduit knowledge projection
  5. Streamline/OwnerRez approved writes

Every repoint runs in shadow first and compares hashes, claims, redactions, and receipts.

Phase 6: deploy the same core into separate client data planes#

  • Roam Free remains the first real proving tenant for every capability.
  • Deploy the same schema/runtime into an LTA-isolated data plane before treating LTA as the reference premium architecture.
  • Migrate through immutable export/import plus reconciliation, not direct database copying without proof.

Phase 7: retire compatibility paths#

  • Retire legacy prompts, q_* echoes, local-only records, direct secret-to-Conduit rendering, and globally unique unit-code assumptions only after consumers have moved and replay tests pass.

This is a strangler migration: wrap, shadow, compare, repoint, then retire. There is no justification for rewriting the proven gates and adapters.

Architecture decisions for Taylor, ordered by dependency#

These should be asked one at a time.

  1. Canonical value model: approve raw versions → fact candidates → explicit canonical decisions → derived artifacts, with no last-write-wins and no projection allowed to become canonical implicitly.
  2. Source authority model: approve field- and context-specific authority records, rather than one global source precedence per client.
  3. Premium isolation boundary: confirm LTA will move to its own data plane before broad production use, while the shared Supabase remains the proving environment and possible future low-cost architecture.
  4. Permanent identity: approve internal tenant-owned UUIDs for every resource and a separate external-identity mapping for all vendor IDs/codes.
  5. Canonical storage rule: approve governed facts/entities as the only new canonical homes; properties columns, amenities JSON, metadata, Notion, and vendor mirrors become compatibility projections.
  6. Content artifact model: approve one generic version/approval/publication ledger for listings, captions, knowledge packs, social posts, websites, compliance outputs, and later bookkeeping deliverables.
  7. Unknown-fact behavior: approve fail-closed handling for guest and operational facts; AI may propose a question or draft, but may not promote a guessed fact into runtime knowledge.
  8. Secret/model policy: approve local-only or tool-retrieval handling for access credentials and other sensitive values; no external AI prompt receives them by default.
  9. Client extensibility contract: approve read APIs, export snapshots, webhooks, scoped service accounts, and client-owned schemas as first-class product surfaces from the first production data plane.
  10. Migration method: approve wrap-and-shadow migration with hash/diff parity gates, not a new greenfield rewrite.

First-principles challenge to the current assumptions#

  • Streamline should not be “the source of truth whenever it has a field.” It should be authoritative only for fields the client assigns to it. Otherwise the vendor remains the data model.
  • Notion should not be the source of truth for Layer 2. It can be the preferred human editing surface, but edits should become governed commands/candidates in the client data plane.
  • A canonical fact is not simply the highest-ranked current source value. It is a time-bounded decision with evidence, policy, and an owner.
  • “Guest-facing” is not sufficient authorization for a secret. Wi-Fi and access credentials require reservation/person/purpose checks and should preferably be retrieved as tools, not embedded in reusable knowledge.
  • A listing description and a guest-messaging knowledge pack should not independently restate the same facts as editable prose. Both should be projections from the same decisions, with separate recipes and audience policies.
  • The data platform should not be optimized around property content alone. Property, reservation, owner, guest, conversation, task, vendor, account, document, and event identities must share the same raw/candidate/decision/derived pattern so the base can support CRM, social, bookkeeping, compliance, and websites.

Bottom line#

The repository has already solved many hard execution problems. The new platform should keep those solutions and place them behind a broader, client-owned data contract.

The single most valuable next decision is whether a canonical value is an overwritable row or an explicit decision over preserved source candidates. The recommendation is the latter. That choice makes source authority, conflict resolution, auditability, client exports, model safety, vendor migration, and future accelerators coherent.