Unclassified

IntegrateWise App-Category Entity Domain Model — Canonical Schema

Governing Rule — 2026-07-28
The Spine is not organized by department. It is organized by what entities ARE (app_category = source), what business function they belong to (business_domain = classification), and when in the startup lifecycle they matter (lifecycle_stage = routing key).


1. Three-Layer Classification

Every canonical entity carries three classification tags beyond its spine identity fields:

  • app_category — the connector/source classification. Determines which integration writes to which entity domain.
  • business_domain — the RBAC classification. Determines who can see/write the entity and which projection rules apply.
  • lifecycle_stage — the routing key. Determines which signals fire, which playbooks activate, and which projections get rebuilt.

Full classification address = (app_category, business_domain, lifecycle_stage).

1.1 App Category Registry

Source layer: the type of tool the entity originates from. Every connector is classified into exactly one primary app category.

app_category_idkeynamedescription
ac_crmcrmCRMCustomer relationship and sales system of record.
ac_marketing_automationmarketing_automationMarketing AutomationCampaign, audience and attribution source.
ac_revenue_operationsrevenue_operationsRevenue OperationsForecast, routing, territory and sales-intelligence source.
ac_support_helpdesksupport_helpdeskSupport / HelpdeskSupport case, service and SLA source.
ac_finance_billingfinance_billingFinance / BillingInvoice, payment, subscription and spend source.
ac_hris_peoplehris_peopleHRIS / PeopleWorkforce and people-operations source.
ac_recruiting_atsrecruiting_atsRecruiting / ATSRecruiting and hiring source.
ac_product_analyticsproduct_analyticsProduct AnalyticsProduct-usage and adoption source.
ac_project_issue_trackingproject_issue_trackingProject / Issue TrackingPlanning, delivery and issue source.
ac_devops_cicddevops_cicdDevOps / CI-CDCode, build, deployment and release source.
ac_observability_monitoringobservability_monitoringObservability / MonitoringAlert, incident and reliability source.
ac_legal_contractlegal_contractLegal / ContractAgreement and compliance source.
ac_it_identityit_identityIT / IdentityIdentity, device, access and security-control source.
ac_communications_emailcommunications_emailCommunications - EmailEmail communication source.
ac_communications_chatcommunications_chatCommunications - ChatChat communication source.
ac_communications_videocommunications_videoCommunications - VideoMeeting, call and recording source.
ac_knowledge_docsknowledge_docsKnowledge / DocsDocument, note and knowledge source.
ac_executive_boardexecutive_boardExecutive / BoardBoard, investor and company-planning source.
ac_marketplace_platformmarketplace_platformMarketplace / PlatformIntegration and platform-runtime source.
ac_integratewise_nativeintegratewise_nativeIntegrateWise NativeHuman-created or governed IntegrateWise record.

1.2 Business Domain Registry

Classification layer: the RBAC domain every entity belongs to. Determines visibility, field restrictions, and projection rules.

business_domain_idkeynamesensitivity
bd_revenuerevenueRevenuerestricted
bd_peoplepeoplePeopleconfidential
bd_productproductProductinternal
bd_operationsoperationsOperationsinternal
bd_financefinanceFinanceconfidential
bd_legallegalLegalconfidential
bd_communicationscommunicationsCommunicationsrestricted
bd_knowledgeknowledgeKnowledgeinternal
bd_platformplatformPlatformrestricted

1.3 Lifecycle Stage Registry

Routing layer: where the tenant/user/entity is in the operational lifecycle.

lifecycle_stagemeaningactive entities / tables
formationTenant onboarding, connectors being installed, no live data yettenants, users, roles, connector_catalog, connector_installations
activationFirst connectors live, data flowing in, first accounts/contacts/deals created+ accounts, contacts, deals, signals (ingestion)
operationDaily run-rate. Pipeline active. Memory accumulating. Playbooks firing.+ tasks, activities, invoices, budgets, playbooks, memory_items
scaleMulti-team RBAC expanding, canvas templates customized per role+ teams, team_members, approval_chains, canvas_overrides, org_memory
governanceAudit, compliance, promotion queue at volume, retention enforced+ audit_log, promotion_queue, retention_policies

Stages are additive, not replacing.


2. App-Category → Entity Domain Routes

Each route defines how an app category maps to a canonical entity type and table, its business domain, lifecycle stage, and event emissions.

route_idapp_categoryentity_typecanonical_tablebusiness_domaindefault_lifecycle_stageevent_types
acr_crm_accountcrmaccountspine_accountsrevenueoperateaccount.created, account.updated
acr_crm_leadcrmleadspine_leadsrevenuesenselead.created, lead.qualified
acr_crm_opportunitycrmopportunityspine_opportunitiesrevenuedecideopportunity.stage_changed, deal.won, deal.lost
acr_marketing_campaignmarketing_automationcampaignspine_campaignsrevenuebuildcampaign.launched, lead.scored, attribution.recorded
acr_revops_workflowrevenue_operationsworkflowspine_workflowsrevenueoperateforecast.published, territory.assigned, quota.set
acr_support_ticketsupport_helpdeskticketspine_ticketsoperationsoperateticket.created, ticket.escalated, ticket.resolved, sla.breached
acr_finance_invoicefinance_billinginvoicespine_invoicesfinanceoperateinvoice.created, payment.received, payment.failed
acr_finance_subscriptionfinance_billingsubscriptionspine_subscriptionsfinanceoperatesubscription.renewed
acr_people_personhris_peoplepersonspine_personspeopleoperateemployee.hired, employee.departed
acr_people_teamhris_peopleteamspine_teamspeopleoperateemployee.onboarded, review.completed, leave.approved
acr_ats_personrecruiting_atspersonspine_personspeoplesensecandidate.applied, interview.scheduled, offer.extended, hire.completed
acr_product_featureproject_issue_trackingfeaturespine_featuresproductbuildissue.created, feature.shipped, bug.resolved
acr_product_sprintproject_issue_trackingsprintspine_sprintsproductbuildsprint.started, milestone.hit
acr_analytics_signalproduct_analyticssignalspine_signalsproductlearnfeature.used, session.started, adoption_tier.changed
acr_devops_releasedevops_cicdreleasespine_releasesproductreleasecommit.pushed, pr.merged, build.passed, deployment.succeeded
acr_observability_incidentobservability_monitoringincidentspine_incidentsproductoperatealert.fired, incident.declared, slo.breached, rca.completed
acr_legal_contractlegal_contractcontractspine_contractslegaldecidecontract.drafted, contract.sent, contract.signed, obligation.due
acr_identity_assetit_identityassetspine_assetsoperationsoperateuser.provisioned, access.granted, certificate.expiring, vulnerability.detected
acr_email_conversationcommunications_emailconversationspine_conversationscommunicationssenseemail.received, email.sent, thread.classified, action.extracted
acr_chat_conversationcommunications_chatconversationspine_conversationscommunicationssensemessage.sent, mention.detected, sentiment.scored
acr_video_meetingcommunications_videomeetingspine_meetingscommunicationsoperatemeeting.held, recording.processed, transcript.ready, action_items.extracted
acr_knowledge_documentknowledge_docsdocumentknowledge_documentsknowledgelearndocument.created, article.published, document.shared, chunk.embedded
acr_board_objectiveexecutive_boardobjectivespine_objectivesoperationsdecidegoal.set, board_item.added, update.sent, funding_round.opened
acr_platform_connectormarketplace_platformconnectorspine_connector_catalogplatformoperateconnector.installed, capability.invoked, automation.triggered, mcp_tool.called

3. Canonical Spine Identity Fields (Every Table)

These fields are immutable spine addresses. Always OMITTED from projections.

  • spine_network_id TEXT PRIMARY KEY — format: {prefix}_{ulid}, globally unique, cross-tenant stable
  • account_id TEXT NOT NULL — tenant this record belongs to
  • created_at TIMESTAMPTZ NOT NULL DEFAULT now()
  • updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
  • version INTEGER NOT NULL DEFAULT 1 — incremented on every canonical write
  • origin TEXT NOT NULL — human | twin | pipeline | system
  • promotion_id TEXT — the promotion_queue.queue_id that wrote this version; null for system-origin
  • lifecycle_stage TEXT NOT NULL — formation | activation | operation | scale | governance
  • app_category TEXT NOT NULL
  • business_domain TEXT NOT NULL

4. Canonical Table Registry

4.1 Formation Stage Tables

tenants

CREATE TABLE tenants (
  spine_network_id TEXT PRIMARY KEY,
  account_id TEXT NOT NULL UNIQUE,
  slug TEXT NOT NULL UNIQUE,
  display_name TEXT NOT NULL,
  plan TEXT NOT NULL DEFAULT 'free',
  lifecycle_stage TEXT NOT NULL DEFAULT 'formation',
  onboarding_status TEXT NOT NULL DEFAULT 'pending',
  primary_domain TEXT,
  timezone TEXT NOT NULL DEFAULT 'UTC',
  locale TEXT NOT NULL DEFAULT 'en',
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  version INTEGER NOT NULL DEFAULT 1,
  origin TEXT NOT NULL DEFAULT 'system',
  promotion_id TEXT,
  app_category TEXT NOT NULL DEFAULT 'platform',
  business_domain TEXT NOT NULL DEFAULT 'identity'
);

users

CREATE TABLE users (
  spine_network_id TEXT PRIMARY KEY,
  account_id TEXT NOT NULL REFERENCES tenants(account_id),
  external_id TEXT NOT NULL,
  email TEXT NOT NULL,
  display_name TEXT NOT NULL,
  avatar_url TEXT,
  role_id TEXT NOT NULL REFERENCES roles(spine_network_id),
  employment_type TEXT NOT NULL DEFAULT 'full_time',
  work_lifecycle_stage TEXT NOT NULL DEFAULT 'onboarding',
  last_active_at TIMESTAMPTZ,
  lifecycle_stage TEXT NOT NULL DEFAULT 'formation',
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  version INTEGER NOT NULL DEFAULT 1,
  origin TEXT NOT NULL DEFAULT 'system',
  promotion_id TEXT,
  app_category TEXT NOT NULL DEFAULT 'platform',
  business_domain TEXT NOT NULL DEFAULT 'identity',
  UNIQUE(account_id, email)
);

roles

CREATE TABLE roles (
  spine_network_id TEXT PRIMARY KEY,
  account_id TEXT NOT NULL REFERENCES tenants(account_id),
  slug TEXT NOT NULL,
  display_name TEXT NOT NULL,
  is_system_role BOOLEAN NOT NULL DEFAULT false,
  parent_role_id TEXT REFERENCES roles(spine_network_id),
  permissions JSONB NOT NULL DEFAULT '[]',
  domain_access JSONB NOT NULL DEFAULT '{}', -- {domain: "full"|"partial"|"none"}
  lifecycle_stage TEXT NOT NULL DEFAULT 'formation',
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  version INTEGER NOT NULL DEFAULT 1,
  origin TEXT NOT NULL DEFAULT 'system',
  promotion_id TEXT,
  app_category TEXT NOT NULL DEFAULT 'platform',
  business_domain TEXT NOT NULL DEFAULT 'identity',
  UNIQUE(account_id, slug)
);

connector_catalog

CREATE TABLE connector_catalog (
  spine_network_id TEXT PRIMARY KEY,
  account_id TEXT NOT NULL DEFAULT 'platform',
  slug TEXT NOT NULL UNIQUE,
  display_name TEXT NOT NULL,
  app_category TEXT NOT NULL,
  business_domain TEXT NOT NULL,
  logo_url TEXT,
  auth_type TEXT NOT NULL, -- oauth2 | api_key | webhook | mcp
  mcp_endpoint TEXT,
  manifest_version TEXT NOT NULL DEFAULT '1.0',
  is_active BOOLEAN NOT NULL DEFAULT true,
  lifecycle_stage TEXT NOT NULL DEFAULT 'formation',
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  version INTEGER NOT NULL DEFAULT 1,
  origin TEXT NOT NULL DEFAULT 'system',
  promotion_id TEXT
);

connector_installations

CREATE TABLE connector_installations (
  spine_network_id TEXT PRIMARY KEY,
  account_id TEXT NOT NULL REFERENCES tenants(account_id),
  connector_id TEXT NOT NULL REFERENCES connector_catalog(spine_network_id),
  installed_by TEXT NOT NULL REFERENCES users(spine_network_id),
  status TEXT NOT NULL DEFAULT 'pending',
  auth_credential_ref TEXT, -- vault reference only, never plaintext
  config JSONB NOT NULL DEFAULT '{}',
  last_sync_at TIMESTAMPTZ,
  last_error TEXT,
  sync_frequency TEXT NOT NULL DEFAULT '15m',
  lifecycle_stage TEXT NOT NULL DEFAULT 'formation',
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  version INTEGER NOT NULL DEFAULT 1,
  origin TEXT NOT NULL DEFAULT 'system',
  promotion_id TEXT,
  app_category TEXT NOT NULL,
  business_domain TEXT NOT NULL,
  UNIQUE(account_id, connector_id)
);

4.2 Activation Stage Tables

accounts

CREATE TABLE accounts (
  spine_network_id TEXT PRIMARY KEY,
  account_id TEXT NOT NULL REFERENCES tenants(account_id),
  name TEXT NOT NULL,
  domain TEXT,
  industry TEXT,
  employee_count INTEGER,
  annual_revenue NUMERIC(18,2),
  health_score NUMERIC(4,3), -- 0-1, computed by pipeline
  tier TEXT, -- strategic | growth | standard | at_risk
  owner_id TEXT REFERENCES users(spine_network_id),
  lifecycle_stage TEXT NOT NULL DEFAULT 'activation',
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  version INTEGER NOT NULL DEFAULT 1,
  origin TEXT NOT NULL,
  promotion_id TEXT,
  app_category TEXT NOT NULL DEFAULT 'crm',
  business_domain TEXT NOT NULL DEFAULT 'revenue'
);

contacts

CREATE TABLE contacts (
  spine_network_id TEXT PRIMARY KEY,
  account_id TEXT NOT NULL REFERENCES tenants(account_id),
  external_account_id TEXT REFERENCES accounts(spine_network_id),
  first_name TEXT NOT NULL,
  last_name TEXT NOT NULL,
  email TEXT,
  phone TEXT,
  title TEXT,
  department TEXT,
  linkedin_url TEXT,
  contact_type TEXT NOT NULL DEFAULT 'external',
  lifecycle_stage TEXT NOT NULL DEFAULT 'activation',
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  version INTEGER NOT NULL DEFAULT 1,
  origin TEXT NOT NULL,
  promotion_id TEXT,
  app_category TEXT NOT NULL DEFAULT 'crm',
  business_domain TEXT NOT NULL DEFAULT 'people'
);

deals

CREATE TABLE deals (
  spine_network_id TEXT PRIMARY KEY,
  account_id TEXT NOT NULL REFERENCES tenants(account_id),
  name TEXT NOT NULL,
  external_account_id TEXT REFERENCES accounts(spine_network_id),
  primary_contact_id TEXT REFERENCES contacts(spine_network_id),
  owner_id TEXT REFERENCES users(spine_network_id),
  stage TEXT NOT NULL DEFAULT 'prospecting',
  value NUMERIC(18,2),
  currency TEXT NOT NULL DEFAULT 'USD',
  close_date DATE,
  probability NUMERIC(4,3),
  deal_type TEXT,
  lost_reason TEXT,
  lifecycle_stage TEXT NOT NULL DEFAULT 'activation',
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  version INTEGER NOT NULL DEFAULT 1,
  origin TEXT NOT NULL,
  promotion_id TEXT,
  app_category TEXT NOT NULL DEFAULT 'crm',
  business_domain TEXT NOT NULL DEFAULT 'revenue'
);

4.3 Operation Stage Tables

tasks

CREATE TABLE tasks (
  spine_network_id TEXT PRIMARY KEY,
  account_id TEXT NOT NULL REFERENCES tenants(account_id),
  title TEXT NOT NULL,
  description TEXT,
  assignee_id TEXT REFERENCES users(spine_network_id),
  created_by TEXT REFERENCES users(spine_network_id),
  related_entity_id TEXT,
  related_entity_type TEXT,
  status TEXT NOT NULL DEFAULT 'open',
  priority TEXT NOT NULL DEFAULT 'normal',
  due_date DATE,
  completed_at TIMESTAMPTZ,
  lifecycle_stage TEXT NOT NULL DEFAULT 'operation',
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  version INTEGER NOT NULL DEFAULT 1,
  origin TEXT NOT NULL,
  promotion_id TEXT,
  app_category TEXT NOT NULL DEFAULT 'project_management',
  business_domain TEXT NOT NULL DEFAULT 'operations'
);

activities

CREATE TABLE activities (
  spine_network_id TEXT PRIMARY KEY,
  account_id TEXT NOT NULL REFERENCES tenants(account_id),
  activity_type TEXT NOT NULL,
  subject TEXT NOT NULL,
  body TEXT,
  performed_by TEXT REFERENCES users(spine_network_id),
  related_entity_id TEXT,
  related_entity_type TEXT, -- call | email | meeting | note | demo | proposal
  participants TEXT[],
  duration_seconds INTEGER,
  occurred_at TIMESTAMPTZ NOT NULL,
  lifecycle_stage TEXT NOT NULL DEFAULT 'operation',
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  version INTEGER NOT NULL DEFAULT 1,
  origin TEXT NOT NULL,
  promotion_id TEXT,
  app_category TEXT NOT NULL DEFAULT 'communication',
  business_domain TEXT NOT NULL DEFAULT 'revenue'
);

signals

CREATE TABLE signals (
  spine_network_id TEXT PRIMARY KEY,
  account_id TEXT NOT NULL REFERENCES tenants(account_id),
  signal_type TEXT NOT NULL,
  subject_entity_id TEXT NOT NULL,
  subject_entity_type TEXT NOT NULL,
  payload JSONB NOT NULL DEFAULT '{}',
  confidence NUMERIC(4,3) NOT NULL DEFAULT 1.0,
  source TEXT NOT NULL,
  fired_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  consumed_by TEXT[],
  lifecycle_stage TEXT NOT NULL DEFAULT 'operation',
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  version INTEGER NOT NULL DEFAULT 1,
  origin TEXT NOT NULL DEFAULT 'pipeline',
  promotion_id TEXT,
  app_category TEXT NOT NULL DEFAULT 'pipeline',
  business_domain TEXT NOT NULL DEFAULT 'operations'
);

invoices

CREATE TABLE invoices (
  spine_network_id TEXT PRIMARY KEY,
  account_id TEXT NOT NULL REFERENCES tenants(account_id),
  external_account_id TEXT REFERENCES accounts(spine_network_id),
  invoice_number TEXT NOT NULL,
  status TEXT NOT NULL DEFAULT 'draft',
  amount NUMERIC(18,2) NOT NULL,
  currency TEXT NOT NULL DEFAULT 'USD',
  due_date DATE,
  paid_at TIMESTAMPTZ,
  line_items JSONB NOT NULL DEFAULT '[]',
  lifecycle_stage TEXT NOT NULL DEFAULT 'operation',
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  version INTEGER NOT NULL DEFAULT 1,
  origin TEXT NOT NULL,
  promotion_id TEXT,
  app_category TEXT NOT NULL DEFAULT 'billing',
  business_domain TEXT NOT NULL DEFAULT 'finance'
);

playbooks

CREATE TABLE playbooks (
  spine_network_id TEXT PRIMARY KEY,
  account_id TEXT NOT NULL REFERENCES tenants(account_id),
  name TEXT NOT NULL,
  trigger_signal TEXT NOT NULL,
  conditions JSONB NOT NULL DEFAULT '[]',
  actions JSONB NOT NULL DEFAULT '[]',
  is_active BOOLEAN NOT NULL DEFAULT true,
  run_count INTEGER NOT NULL DEFAULT 0,
  last_run_at TIMESTAMPTZ,
  lifecycle_stage TEXT NOT NULL DEFAULT 'operation',
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  version INTEGER NOT NULL DEFAULT 1,
  origin TEXT NOT NULL DEFAULT 'human',
  promotion_id TEXT,
  app_category TEXT NOT NULL DEFAULT 'platform',
  business_domain TEXT NOT NULL DEFAULT 'operations'
);

memory_items

CREATE TABLE memory_items (
  spine_network_id TEXT PRIMARY KEY,
  account_id TEXT NOT NULL REFERENCES tenants(account_id),
  scope TEXT NOT NULL, -- personal | organizational | agent | operational
  memory_type TEXT NOT NULL, -- observation | decision | context | fact | signal | continuity_checkpoint
  subject_refs TEXT[] NOT NULL,
  content TEXT,
  content_jsonb JSONB,
  user_id TEXT REFERENCES users(spine_network_id),
  session_id TEXT,
  origin TEXT NOT NULL,
  confidence NUMERIC(4,3),
  retention_policy TEXT NOT NULL DEFAULT '30d',
  expires_at TIMESTAMPTZ,
  promotion_eligible BOOLEAN NOT NULL DEFAULT false,
  promotion_status TEXT NOT NULL DEFAULT 'none', -- none | proposed | approved | committed | rejected
  lifecycle_stage TEXT NOT NULL DEFAULT 'operation',
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  version INTEGER NOT NULL DEFAULT 1,
  promotion_id TEXT,
  app_category TEXT NOT NULL DEFAULT 'platform',
  business_domain TEXT NOT NULL DEFAULT 'operations'
);

4.4 Scale Stage Tables

teams

CREATE TABLE teams (
  spine_network_id TEXT PRIMARY KEY,
  account_id TEXT NOT NULL REFERENCES tenants(account_id),
  name TEXT NOT NULL,
  team_type TEXT NOT NULL DEFAULT 'functional',
  lead_user_id TEXT REFERENCES users(spine_network_id),
  parent_team_id TEXT REFERENCES teams(spine_network_id),
  domain_focus TEXT[],
  lifecycle_stage TEXT NOT NULL DEFAULT 'scale',
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  version INTEGER NOT NULL DEFAULT 1,
  origin TEXT NOT NULL DEFAULT 'human',
  promotion_id TEXT,
  app_category TEXT NOT NULL DEFAULT 'platform',
  business_domain TEXT NOT NULL DEFAULT 'identity'
);

team_members

CREATE TABLE team_members (
  spine_network_id TEXT PRIMARY KEY,
  account_id TEXT NOT NULL REFERENCES tenants(account_id),
  team_id TEXT NOT NULL REFERENCES teams(spine_network_id),
  user_id TEXT NOT NULL REFERENCES users(spine_network_id),
  team_role TEXT NOT NULL DEFAULT 'member',
  lifecycle_stage TEXT NOT NULL DEFAULT 'scale',
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  version INTEGER NOT NULL DEFAULT 1,
  origin TEXT NOT NULL DEFAULT 'human',
  promotion_id TEXT,
  app_category TEXT NOT NULL DEFAULT 'platform',
  business_domain TEXT NOT NULL DEFAULT 'identity',
  UNIQUE(team_id, user_id)
);

approval_chains

CREATE TABLE approval_chains (
  spine_network_id TEXT PRIMARY KEY,
  account_id TEXT NOT NULL REFERENCES tenants(account_id),
  capability TEXT NOT NULL,
  approver_role_id TEXT NOT NULL REFERENCES roles(spine_network_id),
  escalation_role_id TEXT REFERENCES roles(spine_network_id),
  escalation_after_hours INTEGER NOT NULL DEFAULT 24,
  is_active BOOLEAN NOT NULL DEFAULT true,
  lifecycle_stage TEXT NOT NULL DEFAULT 'scale',
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  version INTEGER NOT NULL DEFAULT 1,
  origin TEXT NOT NULL DEFAULT 'human',
  promotion_id TEXT,
  app_category TEXT NOT NULL DEFAULT 'platform',
  business_domain TEXT NOT NULL DEFAULT 'identity',
  UNIQUE(account_id, capability)
);

canvas_overrides

CREATE TABLE canvas_overrides (
  spine_network_id TEXT PRIMARY KEY,
  account_id TEXT NOT NULL REFERENCES tenants(account_id),
  projection_key TEXT NOT NULL,
  template_level TEXT NOT NULL, -- tenant | user
  user_id TEXT REFERENCES users(spine_network_id),
  overrides JSONB NOT NULL DEFAULT '{}',
  is_active BOOLEAN NOT NULL DEFAULT true,
  lifecycle_stage TEXT NOT NULL DEFAULT 'scale',
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  version INTEGER NOT NULL DEFAULT 1,
  origin TEXT NOT NULL DEFAULT 'human',
  promotion_id TEXT,
  app_category TEXT NOT NULL DEFAULT 'platform',
  business_domain TEXT NOT NULL DEFAULT 'operations'
);

4.5 Governance Stage Tables

audit_log

CREATE TABLE audit_log (
  spine_network_id TEXT PRIMARY KEY,
  account_id TEXT NOT NULL REFERENCES tenants(account_id),
  actor_id TEXT,
  action TEXT NOT NULL, -- create | update | promote | approve | reject
  target_entity_id TEXT NOT NULL,
  target_entity_type TEXT NOT NULL,
  before_version INTEGER,
  after_version INTEGER,
  diff JSONB,
  promotion_id TEXT,
  ip_address TEXT,
  user_agent TEXT,
  occurred_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  lifecycle_stage TEXT NOT NULL DEFAULT 'governance',
  version INTEGER NOT NULL DEFAULT 1,
  origin TEXT NOT NULL,
  app_category TEXT NOT NULL DEFAULT 'platform',
  business_domain TEXT NOT NULL DEFAULT 'governance'
);

retention_policies

CREATE TABLE retention_policies (
  spine_network_id TEXT PRIMARY KEY,
  account_id TEXT NOT NULL REFERENCES tenants(account_id),
  entity_type TEXT NOT NULL,
  business_domain TEXT NOT NULL,
  retention_days INTEGER NOT NULL, -- -1 = permanent
  archive_after_days INTEGER,
  delete_after_days INTEGER,
  applies_to_scopes TEXT[] NOT NULL DEFAULT ARRAY['personal','organizational','agent'],
  lifecycle_stage TEXT NOT NULL DEFAULT 'governance',
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  version INTEGER NOT NULL DEFAULT 1,
  origin TEXT NOT NULL DEFAULT 'system',
  promotion_id TEXT,
  app_category TEXT NOT NULL DEFAULT 'platform',
  business_domain TEXT NOT NULL DEFAULT 'governance',
  UNIQUE(account_id, entity_type)
);

promotion_queue

CREATE TABLE promotion_queue (
  spine_network_id TEXT PRIMARY KEY,
  account_id TEXT NOT NULL REFERENCES tenants(account_id),
  memory_item_id TEXT NOT NULL REFERENCES memory_items(spine_network_id),
  memory_scope TEXT NOT NULL,
  memory_type TEXT NOT NULL,
  subject_refs TEXT[] NOT NULL,
  canonical_domain TEXT NOT NULL,
  canonical_entity_type TEXT NOT NULL,
  proposed_by TEXT NOT NULL,
  proposed_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  confidence NUMERIC(4,3),
  origin TEXT NOT NULL,
  promotion_status TEXT NOT NULL DEFAULT 'proposed', -- proposed | approved | committed | rejected
  reviewed_by TEXT,
  reviewed_at TIMESTAMPTZ,
  rejection_reason TEXT,
  committed_at TIMESTAMPTZ,
  canonical_record_id TEXT,
  canonical_version INTEGER,
  lifecycle_stage TEXT NOT NULL DEFAULT 'governance',
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  version INTEGER NOT NULL DEFAULT 1,
  app_category TEXT NOT NULL DEFAULT 'platform',
  business_domain TEXT NOT NULL DEFAULT 'governance'
);

5. Memory Architecture

Four distinct memory scopes with different contracts, write authorities, lifetimes, and promotion paths.

ScopePersisted InKeyed ByTTL / LifecycleWho Can WriteWho Can ReadPromotable
PersonalDurable Objects + KVuser_id + memory_type + subject_snid30 daysUser direct; Twin proposes with user approvalUser onlyYes
OrganizationalPostgres / D1tenant_id + entity_snid + memory_typePermanentTwin proposed + human approved; human with write RBACAll users with read RBAC on domain + agents in session contextYes
AgentDurable Objectssession_id + entity_snid + (account_id + user_id)Session onlyTwin agent only during sessionTwin agent for that session only; user sees output, not raw agent memoryYes
OperationalKV / Redisaccount_id + entity_type + projection_key7 daysSystem pipeline onlyProjection Engine internal only; no direct human readFalse

Every memory item carries:

  • scope: personal | organizational | agent | operational
  • memory_type: observation | decision | context | fact | signal | continuity_checkpoint
  • subject_refs: entity SNIDs
  • content: text or JSONB payload
  • origin: human | twin | pipeline | system
  • confidence: 0-1 for AI-origin
  • retention_policy: session | 7d | 30d | 90d | permanent
  • promotion_eligible: boolean
  • promotion_status: none | proposed | approved | committed | rejected

6. Promotion Queue Lifecycle

The only path from memory to canonical truth.

MEMORY ITEM (any scope)
  -> promotion_eligible = true
  -> [PROPOSED]
     Auto-propose: agent scope, confidence >= 0.85, entity exists
     Manual-propose: human flags any memory item
  -> [REVIEW GATE]
     Auto-approve: system-origin facts, pipeline signals confidence = 1.0
     Human-approve: Twin observations, decisions, org memory, confidence < 0.85
  -> [APPROVED] -> COMMIT WORKER -> Canonical DB append-only write -> promotion_status = committed
  -> [REJECTED] -> promotion_status = rejected, reason logged, memory retained

promotion_queue table fields:

  • queue_id TEXT PRIMARY KEY — format: pq_{ulid}
  • memory_item_id TEXT NOT NULL REFERENCES memory_items(spine_network_id)
  • memory_scope TEXT NOT NULL
  • memory_type TEXT NOT NULL
  • subject_refs TEXT[] NOT NULL
  • canonical_domain TEXT NOT NULL
  • canonical_entity_type TEXT NOT NULL
  • proposed_by TEXT NOT NULL
  • proposed_at TIMESTAMPTZ NOT NULL DEFAULT now()
  • confidence NUMERIC(4,3)
  • origin TEXT NOT NULL
  • promotion_status TEXT NOT NULL DEFAULT 'proposed'
  • reviewed_by TEXT
  • reviewed_at TIMESTAMPTZ
  • rejection_reason TEXT
  • committed_at TIMESTAMPTZ
  • canonical_record_id TEXT
  • canonical_version INTEGER

7. Connector Extension Schema

7.1 connector_extensions

Sidecar table for connector-specific fields without polluting canonical schema.

CREATE TABLE connector_extensions (
  spine_network_id TEXT PRIMARY KEY,
  account_id TEXT NOT NULL REFERENCES tenants(account_id),
  canonical_entity_id TEXT NOT NULL,
  canonical_entity_type TEXT NOT NULL,
  connector_id TEXT NOT NULL REFERENCES connector_catalog(spine_network_id),
  installation_id TEXT NOT NULL REFERENCES connector_installations(spine_network_id),
  source_record_id TEXT NOT NULL,
  source_record_url TEXT,
  extension_data JSONB NOT NULL DEFAULT '{}',
  schema_version TEXT NOT NULL DEFAULT '1.0',
  last_synced_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  sync_hash TEXT,
  lifecycle_stage TEXT NOT NULL DEFAULT 'activation',
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  version INTEGER NOT NULL DEFAULT 1,
  origin TEXT NOT NULL DEFAULT 'pipeline',
  promotion_id TEXT,
  app_category TEXT NOT NULL,
  business_domain TEXT NOT NULL,
  UNIQUE(canonical_entity_id, connector_id)
);

7.2 connector_extension_schemas

CREATE TABLE connector_extension_schemas (
  spine_network_id TEXT PRIMARY KEY,
  account_id TEXT NOT NULL DEFAULT 'platform',
  connector_id TEXT NOT NULL REFERENCES connector_catalog(spine_network_id),
  manifest_version TEXT NOT NULL,
  entity_type TEXT NOT NULL,
  fields JSONB NOT NULL DEFAULT '[]',
  is_active BOOLEAN NOT NULL DEFAULT true,
  lifecycle_stage TEXT NOT NULL DEFAULT 'activation',
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  version INTEGER NOT NULL DEFAULT 1,
  origin TEXT NOT NULL DEFAULT 'system',
  promotion_id TEXT,
  app_category TEXT NOT NULL,
  business_domain TEXT NOT NULL,
  UNIQUE(connector_id, manifest_version, entity_type)
);

7.3 connector_extension_registry

CREATE TABLE connector_extension_registry (
  spine_network_id TEXT PRIMARY KEY,
  account_id TEXT NOT NULL REFERENCES tenants(account_id),
  installation_id TEXT NOT NULL REFERENCES connector_installations(spine_network_id),
  connector_id TEXT NOT NULL REFERENCES connector_catalog(spine_network_id),
  entity_type TEXT NOT NULL,
  extension_count INTEGER NOT NULL DEFAULT 0,
  last_extension_at TIMESTAMPTZ,
  schema_version TEXT NOT NULL,
  lifecycle_stage TEXT NOT NULL DEFAULT 'activation',
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  version INTEGER NOT NULL DEFAULT 1,
  origin TEXT NOT NULL DEFAULT 'system',
  promotion_id TEXT,
  app_category TEXT NOT NULL,
  business_domain TEXT NOT NULL,
  UNIQUE(account_id, installation_id, entity_type)
);

7.4 Extension Merge Rules

  1. RBAC governs extension field visibility via rbac_visible arrays in the connector manifest.
  2. Extension fields are namespaced: salesforce.lead_source, hubspot.hs_lead_status.
  3. Canonical fields always win on conflict.
  4. Merge happens at projection time: canonical + permitted namespaced extension fields + field-level RBAC.

7.5 User Work Lifecycle Stage

users.work_lifecycle_stage dimension:

  • onboarding — simplified canvas, personal memory initialized but empty
  • active — full canvas, personal memory accumulating, Twin active
  • context_switching — canvas rebuilding, previous projection archived, personal memory tagged with role_change
  • offboarding — read-only canvas, no write actions, memory promoted/archived per retention policy, Twin sessions closed
  • inactive — no canvas, auth blocked, memory retained per retention policy

Written by platform at key events: invite accepted, first connector configured, role change detected, offboarding initiated, account suspended.


8. Adaptive Workbench Tuner Schema

8.1 workbench_signals

CREATE TABLE workbench_signals (
  spine_network_id TEXT PRIMARY KEY,
  account_id TEXT NOT NULL REFERENCES tenants(account_id),
  user_id TEXT NOT NULL REFERENCES users(spine_network_id),
  session_id TEXT NOT NULL,
  signal_type TEXT NOT NULL,
  projection_key TEXT NOT NULL,
  block_id TEXT,
  column_id TEXT,
  entity_type TEXT,
  payload JSONB NOT NULL DEFAULT '{}',
  occurred_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  lifecycle_stage TEXT NOT NULL DEFAULT 'operation',
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  version INTEGER NOT NULL DEFAULT 1,
  origin TEXT NOT NULL DEFAULT 'system',
  promotion_id TEXT,
  app_category TEXT NOT NULL DEFAULT 'platform',
  business_domain TEXT NOT NULL DEFAULT 'operations'
);

8.2 tuner_proposals

CREATE TABLE tuner_proposals (
  spine_network_id TEXT PRIMARY KEY,
  account_id TEXT NOT NULL REFERENCES tenants(account_id),
  user_id TEXT REFERENCES users(spine_network_id), -- null = tenant-level proposal
  projection_key TEXT NOT NULL,
  template_level TEXT NOT NULL, -- user | tenant
  proposal_type TEXT NOT NULL, -- block_reorder | column_hide | filter_default | sort_default | block_collapse | action_promote | action_remove | view_reorder
  target_block_id TEXT,
  target_column_id TEXT,
  proposed_change JSONB NOT NULL,
  signal_count INTEGER NOT NULL DEFAULT 1,
  confidence NUMERIC(4,3) NOT NULL,
  auto_approve BOOLEAN NOT NULL DEFAULT false,
  promotion_status TEXT NOT NULL DEFAULT 'none',
  promotion_queue_id TEXT,
  lifecycle_stage TEXT NOT NULL DEFAULT 'scale',
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  version INTEGER NOT NULL DEFAULT 1,
  origin TEXT NOT NULL DEFAULT 'system',
  promotion_id TEXT,
  app_category TEXT NOT NULL DEFAULT 'platform',
  business_domain TEXT NOT NULL DEFAULT 'operations'
);

8.3 Tuner Signal Types

signal_typetriggertuner interpretation
block_skippedUser scrolls past a block without interactingLow-value block for this role; candidate for collapse/reorder
block_collapsedUser manually collapses a blockStrong preference for hidden-by-default
column_hiddenUser hides a table columnLow-value column; candidate for default-hidden
column_pinnedUser pins a column leftHigh-value column; candidate for wider default width
filter_appliedUser applies a filter chipFrequent filter; candidate for default filter
filter_clearedUser clears default filterDefault filter is wrong
row_clickedUser opens row detailSignals cared-about entities; feeds Twin context
kpi_tile_clickedUser drills into KPI tileKPI is high-value; candidate for promotion to header
action_usedUser triggers a row actionHigh-value action; candidate for more prominent placement
action_ignoredAction exists but unused over N sessionsAction may be irrelevant for this role
view_switchedUser switches between viewsDefault view may be wrong
sort_changedUser changes sort orderDefault sort is wrong
session_durationTime spent on a surfaceLow duration = surface may not serve this user

8.4 Auto-Tuning Eligibility Thresholds

These thresholds apply only to reversible presentation preferences. They never
authorize canonical writes, organizational policy changes or external actions.
Tenant-level changes require human approval.

proposal_typetemplate_leveltrigger signal typesmin signal countmin confidencelocal presentation auto-apply eligible
column_hideusercolumn_hidden3 across 3+ sessions0.80true
column_hidetenantcolumn_hidden100.90false
filter_defaultuserfilter_applied, filter_cleared50.85true
filter_defaulttenantfilter_applied150.90false
sort_defaultusersort_changed30.80true
sort_defaulttenantsort_changed100.88false
block_collapseuserblock_collapsed20.75true
block_collapsetenantblock_collapsed80.85false
block_reorderuserblock_skipped, session_duration50.80false
block_reordertenantblock_skipped200.85false
action_promoteuseraction_used50.85false
action_promotetenantaction_used200.90false
action_removeuseraction_ignored100.90false
action_removetenantaction_ignored300.92false
view_reordertenantview_switched150.85false
kpi_promoteuserkpi_tile_clicked40.80false

Tenant-level proposals are always human-reviewed.

8.5 Tuner Proposal JSONB Shape

{
  "proposal_type": "column_hide",
  "target": {
    "projection_key": "proj:sales_rep:revenue:acct_01J9:pipeline",
    "block_id": "b_deals_grid",
    "column_field": "margin"
  },
  "change": {
    "operation": "set_field_state",
    "field": "margin",
    "from": "VISIBLE",
    "to": "OMITTED"
  },
  "rationale": "Field hidden by user in 4 of last 5 sessions.",
  "signal_summary": {
    "signal_type": "column_hidden",
    "signal_count": 4,
    "sessions_observed": 5,
    "first_observed": "2026-07-20T09:14:00Z",
    "last_observed": "2026-07-27T16:42:00Z"
  }
}

9. Canvas View Projection JSONB Schema

Canvas projections are stored as JSONB in projection_manifests.

9.1 projection_manifests Table

CREATE TABLE projection_manifests (
  manifest_id TEXT PRIMARY KEY, -- mfst_{ulid}
  projection_key TEXT NOT NULL, -- proj:{role_slug}:{domain}:{account_id}:{view_name}
  role_slug TEXT NOT NULL,
  domain TEXT NOT NULL,
  view_name TEXT NOT NULL,
  template_level TEXT NOT NULL, -- system | tenant | user
  tenant_id TEXT, -- NULL for system templates
  user_id TEXT, -- NULL for system and tenant templates
  version INTEGER NOT NULL DEFAULT 1,
  canvas JSONB NOT NULL,
  created_by TEXT NOT NULL,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  archived_at TIMESTAMPTZ -- NULL if active
);

9.2 Canonical JSONB Canvas Structure

{
  "manifest_id": "mfst_01J9XK...",
  "projection_key": "proj:sales_rep:revenue:acct_01J9:pipeline",
  "view_name": "Pipeline",
  "role_slug": "sales_rep",
  "domain": "revenue",
  "zones": [
    {
      "zone_id": "z_header",
      "zone_type": "header",
      "blocks": [
        {
          "block_id": "b_title",
          "block_type": "markdown",
          "content": "## My Pipeline",
          "rbac_visible": ["sales_rep", "sales_manager", "cro"]
        },
        {
          "block_id": "b_kpi",
          "block_type": "kpi_strip",
          "tiles": [
            {
              "label": "Open Pipeline",
              "formula": "[deals].Filter([owner_id]=User().Id And [status]='open').[value].Sum()",
              "format": "currency"
            },
            {
              "label": "Deals This Month",
              "formula": "[deals].Filter([owner_id]=User().Id And [close_date]<=Today()).Count()",
              "format": "number"
            },
            {
              "label": "Win Rate",
              "formula": "[deals].Filter([owner_id]=User().Id And [status]='won').Count() / [deals].Filter([owner_id]=User().Id).Count()",
              "format": "percent"
            },
            {
              "label": "Avg Deal Size",
              "formula": "[deals].Filter([owner_id]=User().Id And [status]='open').[value].Average()",
              "format": "currency"
            }
          ]
        }
      ]
    },
    {
      "zone_id": "z_main",
      "zone_type": "work_surface",
      "blocks": [
        {
          "block_id": "b_deals_grid",
          "block_type": "table",
          "entity": "deals",
          "filter_formula": "[owner_id] = User().Id And [status] != 'lost'",
          "sort": [{ "field": "close_date", "direction": "asc" }],
          "columns": [
            { "field": "name", "label": "Deal", "width": 200, "rbac_field_state": "VISIBLE" },
            {
              "field": "account_name",
              "label": "Account",
              "width": 160,
              "rbac_field_state": "VISIBLE"
            },
            { "field": "stage", "label": "Stage", "width": 120, "rbac_field_state": "VISIBLE" },
            { "field": "value", "label": "Value", "width": 100, "rbac_field_state": "VISIBLE" },
            {
              "field": "close_date",
              "label": "Close Date",
              "width": 110,
              "rbac_field_state": "VISIBLE"
            },
            { "field": "margin", "label": "Margin", "width": 80, "rbac_field_state": "OMITTED" },
            { "field": "owner_id", "label": "Owner", "width": 120, "rbac_field_state": "VISIBLE" }
          ],
          "row_actions": [
            {
              "label": "Update Stage",
              "capability": "deal.update_stage",
              "approval_required": false
            },
            {
              "label": "Log Activity",
              "capability": "deal.log_activity",
              "approval_required": false
            },
            {
              "label": "Request Discount",
              "capability": "deal.request_discount",
              "approval_required": true
            }
          ]
        }
      ]
    },
    {
      "zone_id": "z_twin",
      "zone_type": "twin_panel",
      "blocks": [
        {
          "block_id": "b_twin",
          "block_type": "twin_panel",
          "activation": "on_row_click",
          "session_scoped": true,
          "read_entities": ["deals", "accounts", "signals", "tasks"],
          "write_mode": "proposal_only",
          "memory_scope": "agent"
        }
      ]
    }
  ]
}

9.3 Canvas Block Type Registry

block_typepurposedata bindingRBAC enforcementkey JSONB fields
calloutColoured alert/info/tip/critical boxStatic text or inline formularbac_visible[] arrayblock_type, style, content, dismissible, icon, rbac_visible[]
markdownRich text paragraph/headings/listsStatic content onlyrbac_visible[]block_type, content, rbac_visible[]
kpi_stripHorizontal KPI tilesCFL formula against RBAC-filtered Operational DBPost-RBAC formula resultblock_type, tiles[] with label, formula, format, tooltip
tableFull grid table bound to entity collectionentity, filter_formula, columns[], sort[]Column rbac_field_state; row-level filter_formulablock_type, entity, filter_formula, columns[], sort[], group_by, row_actions[], page_size
card_gridCard layout over entity rowsSame as table, rendered as cardsColumn rbac_field_state; row-level filter_formulablock_type, entity, filter_formula, card_fields[], sort[], row_actions[]
chartBar/line/pie/area chartCFL aggregate or entity + group_by + measurePost-RBACblock_type, chart_type, formula or {entity, group_by, measure, filter_formula}, x_axis, y_axis, color_by
timelineHorizontal timeline of eventsentity + filter_formula + event_field + label_fieldRow-level filter_formulablock_type, entity, filter_formula, event_field, label_field, color_by_field, zoom_default
formInput form for create/updateentity, fields[] from entity schemaOnly writable fields for role rendered; submit gated by capability RBACblock_type, entity, form_mode, fields[], submit_capability, approval_required
buttonAction triggercapability_key, payload_formulaCapability RBAC at invocationblock_type, label, capability_key, payload_formula, approval_required, confirm_message, disabled_formula
twin_panelContextual AI panelSession-scoped read-only projectionRead: RBAC-filtered agent projection; write: NONEblock_type, activation, session_scoped, read_entities[], write_mode, memory_scope, approval_card_enabled
approval_cardInline approval card for pending Promotion Queue recordpromotion_id, proposal payload, evidence refsApprover RBACblock_type, promotion_id, proposal_summary, evidence_refs[], confidence, actions, expiry_at
dividerVisual separatorNoneAlways visibleblock_type, style

9.4 Canvas Manifest Registry — System Templates Per Role

RoleView NameDomainprojection_keyzone layout
Sales RepPipelineRevenueproj:sales_rep:revenue:{acct}:pipelineheader + main + twin
Sales RepMy LeadsRevenueproj:sales_rep:revenue:{acct}:leadsheader + main + twin
Sales ManagerTeam PipelineRevenueproj:sales_mgr:revenue:{acct}:team_pipelineheader + main + twin
CRO / VP SalesRevenue DashboardRevenueproj:cro:revenue:{acct}:dashboardheader + chart_row + main + twin
CS ManagerAccount GridRevenue+Operationsproj:cs_mgr:revenue:{acct}:accountsheader + main + twin
CS ManagerRenewals PipelineRevenueproj:cs_mgr:revenue:{acct}:renewalsheader + main + twin
Finance ManagerInvoice DashboardFinanceproj:finance:finance:{acct}:invoicesheader + main + twin
Finance ManagerCashflow ForecastFinanceproj:finance:finance:{acct}:cashflowheader + chart_row + main + twin
HR ManagerPeople DirectoryPeopleproj:hr_mgr:people:{acct}:peopleheader + main + twin
HR ManagerHiring PipelinePeopleproj:hr_mgr:people:{acct}:hiringheader + main + twin
Engineering ManagerSprint BoardProductproj:eng_mgr:product:{acct}:sprintheader + main + twin
Engineering ManagerIncident DashboardProduct+Operationsproj:eng_mgr:product:{acct}:incidentsheader + main + twin
Support AgentTicket QueueOperationsproj:support:operations:{acct}:queueheader + main + twin
IT ManagerSecurity DashboardOperations+Platformproj:it_mgr:operations:{acct}:securityheader + main + twin
CEO / FounderCompany PulseAll Domainsproj:ceo:all:{acct}:pulseheader + chart_row + main + twin
AI TwinContextual PanelSession-scopedproj:twin:{acct}:{session}:paneltwin_panel only

10. RBAC View Projection Model

Every view is a projection, not a raw DB read. The Projection Engine applies three filters before data reaches the Operational DB cache:

  1. Domain Filter — which entity types this role can see at all
  2. Field Filter — which fields within those entities are visible (field-level RBAC)
  3. Row Filter — which rows are visible (ownership, team scope, account scope)

projection_key format: proj:{role_slug}:{domain}:{account_id}:{view_name}

Resolution flow:

USER OPENS A VIEW
  -> Projection Engine: role_id + domain + lifecycle_stage + view_name
     -> CACHE HIT (Operational DB / KV): return in < 50ms
     -> CACHE MISS: query Canonical DB with all three RBAC filters
                    shape result into projection_manifest layout (JSONB)
                    write to Operational DB with TTL
                    return to workbench

10.1 Field Visibility States

  • VISIBLE — field is included in the projection, rendered normally
  • MASKED — field is included but value replaced with [RESTRICTED] for audit trail purposes
  • OMITTED — field is not included in the projection at all

Immutable fields (spine_network_id, account_id, created_at, origin, promotion_id) are always OMITTED from projections.

10.2 RBAC Projection Matrix

RoleBusiness DomainEntities Visible (full)Entities Visible (partial)Entities HiddenField-Level RestrictionsRow-Level Scope
Platform OperatorRevenue, People, Product, Operations, Finance, Legal, Communications, Knowledge, PlatformNone — full schema visible across all tenantsNoneNoneNo field restrictions. Raw spine_network_id and account_id visible for debugging.All tenants, all workspaces
Tenant AdminRevenue, People, Product, Operations, Finance, Legal, Communications, Knowledge, PlatformAll entities within own tenant: accounts, contacts, leads, deals, employees, positions, invoices, contracts, tickets, features, bugs, deployments, connectors, users, roles, permissions, audit_eventsNoneOther tenants’ datacompensation_records visible only if also HR Manager role; security_events visible only if also IT Manager role. compensation_records.salary, compensation_records.equity OMITTED unless HR Manager role also held.Own tenant only
CEO / FounderRevenue, People, Product, Operations, Finance, Legal, Communications, Knowledgeaccounts, contacts, deals, opportunities, leads, employees, positions, teams, invoices, payments, budgets, cashflow_snapshots, contracts, obligations, tickets, features, bugs, releases, deployments, incidents, projects, milestones, strategic_goals, board_items, investor_updates, fundraising_pipeline, company_metrics, signals, proposals, approvalsNoneNoneNo field restrictions.All tenants, all accounts, all workspaces
CRO / VP SalesRevenue, Communications, Knowledgeleads, contacts, accounts, opportunities, deals, quotes, sales_activities, sales_sequences, forecast_snapshots, routing_rules, territories, quota_plans, revenue_metrics, attribution_events, campaigns (read), communication_threads, messages, calendar_events, meetings, calls, knowledge_articlesinvoices (status + overdue_count only), contracts (status + expiry_date only), employees (name + title only for team members)compensation_records, budgets (detail), expenses, vulnerabilities, bugs, deployments, payrollinvoices.amount OMITTED. contracts.terms_text OMITTED. contracts.value MASKED. employees fields except name, title, department OMITTED.All accounts in tenant
Sales ManagerRevenue, Communications, Knowledgeleads, contacts, accounts, opportunities, deals, quotes, sales_activities, sales_sequences, forecast_snapshots, communication_threads, messages, calendar_events, meetings, callsinvoices (status only), contracts (status + expiry only), employees (own team: name + title only)compensation_records, budgets, expenses, all Product entities, all People entities except own teaminvoices.amount OMITTED. contracts.value OMITTED. employees fields except name, title OMITTED.Own team only; assigned accounts
Sales RepRevenue, Communications, Knowledgeleads (own), contacts (own accounts), accounts (assigned), opportunities (own), deals (own), quotes (own), sales_activities (own), communication_threads (own), messages (own), calendar_events (own), calls (own)accounts (assigned only — health score visible, no billing detail), knowledge_articles (public)All Finance, Legal, People, Product, Platform entities. Accounts not assigned to self.accounts.billing_status OMITTED. accounts.ltv OMITTED. deals.margin OMITTED.Own accounts, own contacts, own opportunities, own deals, own quotes
Customer Success ManagerRevenue, Operations, Communications, Knowledgeaccounts (assigned), account_contacts, account_health_logs, account_tasks, account_playbooks, account_signals, renewals, adoption_milestones, tickets (linked to own accounts), tasks (own + account), communication_threads (own accounts), meetings, calls, knowledge_articlesdeals (stage + close_date only), invoices (billing_status + overdue_count only), contracts (expiry_date + renewal_date only), employees (name + title only)compensation_records, budgets, expenses, leads (unassigned), all Product internals, all IT/Securitydeals.value OMITTED. invoices.amount OMITTED. contracts.terms_text OMITTED. employees fields except name, title OMITTED.Own accounts only
Marketing ManagerRevenue, Communications, Knowledgecampaigns, campaign_members, content_assets, attribution_events, audience_segments, marketing_spend, forms, leads (all), contacts (all), communication_threads, messages, knowledge_articlesaccounts (name + tier + industry only), deals (stage + value range only), invoices (none — omitted)compensation_records, contracts, tickets, features, bugs, deployments, employeesaccounts.health_score OMITTED. accounts.billing_status OMITTED. deals.margin OMITTED.All leads, all contacts
RevOps ManagerRevenue, Operations, Knowledgepipelines, pipeline_stages, routing_rules, territories, quota_plans, forecast_models, revenue_metrics, leads (all), deals (all), accounts (all), contacts (all), projects, milestones, workflows, operational_metricsinvoices (revenue metrics only), employees (headcount + department only), contracts (status only)compensation_records (individual), tickets, bugs, deployments, security_eventscompensation_records.salary OMITTED. invoices.amount OMITTED.All accounts, all tenant
Finance Manager / CFOFinance, Legal, Operations, Knowledgeinvoices, payments, subscriptions, expenses, budgets, vendors, cashflow_snapshots, company_metrics, fundraising_pipeline, contracts, obligations, legal_requests, projects, milestones, operational_metricsaccounts (billing_status + ltv + arr only), deals (value + close_date only), employees (headcount + cost_band only)compensation_records (individual salary), communications (personal), product_events, bugs, deploymentscompensation_records.salary OMITTED. communication_threads.body OMITTED. employees.performance_rating OMITTED.All accounts, all tenant
Legal CounselLegal, Finance, Operations, Knowledgecontracts, contract_parties, obligations, legal_requests, policies, compliance_controls, evidence_requests, invoices (value + status), vendors, employees (employment_terms only), accounts (contract status)deals (value + close_date only), projects (legal milestones only), company_metrics (fundraising)compensation_records (individual), communication_threads (personal), product_events, tickets, bugscompensation_records.salary OMITTED. communication_threads.body OMITTED. deals.margin OMITTED.All contracts, all tenant
HR ManagerPeople, Finance, Knowledgeemployees, positions, teams, onboarding_plans, performance_cycles, leave_records, compensation_records, job_requisitions, candidates, interviews, offers, people_signalsaccounts (name only — for client-facing employee context), projects (people-related only)deals, invoices, contracts, tickets, bugs, deployments, communication_threads (personal), signals (non-people)accounts.health_score OMITTED. deals.value OMITTED. invoices.amount OMITTED.All employees, all tenant
Engineering ManagerProduct, Operations, Communications, Knowledgefeatures, bugs, sprints, roadmap_items, releases, repositories, deployments, incidents, alerts, slo_records, post_mortems, tasks (engineering), projects (engineering), milestones, communication_threads (own team), meetings (own team), knowledge_articlesaccounts (adoption_tier + health_score only), employees (own team: name + title + performance_rating)compensation_records (salary/equity), invoices, contracts, leads, deals, marketing entitiescompensation_records.salary OMITTED. compensation_records.equity OMITTED. accounts.arr OMITTED.Own team items
Product ManagerProduct, Revenue, Communications, Knowledgefeatures, bugs, roadmap_items, sprints, releases, requirements, product_events, adoption_milestones, accounts (adoption_tier + health_score), communication_threads (own), meetings, knowledge_articlesdeals (stage only), employees (name + title only), invoices (none)compensation_records, contracts, legal_requests, security_events, deployments (infra detail)compensation_records OMITTED. contracts.value OMITTED. deals.margin OMITTED.All projects, all tenant
Support AgentOperations, Communications, Knowledgetickets, cases, sla_policies, sla_events, escalations, support_interactions, csat_responses, tasks (own), communication_threads (own), messages (own), knowledge_articlesaccounts (name + tier + health_score only), contacts (name + email + role only)compensation_records, invoices, contracts, deals, bugs (internal), deployments, employeesaccounts.arr OMITTED. accounts.billing_status OMITTED. contacts.personal_phone OMITTED.Own tickets
IT ManagerOperations, Platform, Knowledgesystems, assets, licenses, certificates, vulnerabilities, access_requests, security_controls, incidents (IT), connectors, connections, api_clients, api_keys, audit_events, deployments (infra)employees (name + provisioning_status only), accounts (system_usage only)compensation_records, invoices, contracts, deals, marketing entities, product_eventscompensation_records OMITTED. invoices.amount OMITTED. contracts.terms_text OMITTED.All systems, all tenant
Operations ManagerOperations, Knowledgeprojects, milestones, dependencies, processes, workflows, operational_metrics, tasks (all), work_items (all), queues, assignments, sla_policies, vendors, strategic_goals, board_itemsaccounts (name + health_score only), employees (name + team only), invoices (budget_status only)compensation_records, deals (detail), contracts (detail), bugs, deployments, security_eventscompensation_records OMITTED. deals.value OMITTED. contracts.terms_text OMITTED.All projects, all workflows, all tenant
AI Twin (Agent Read Projection)Revenue, Operations, Product, Communications, Knowledgeaccounts (health_score, tier, signals), contacts (name, role, last_contact), deals (stage, value, close_date), tickets (status, priority, sla_status), features (status, adoption), tasks (title, status, due_at), signals (all), proposals (pending), communication_threads (entity-linked, session-scoped), knowledge_articles, memory_items (org scope, agent scope)employees (name + title only), invoices (billing_status only), contracts (expiry_date only)compensation_records, budgets, expenses, security_events, credential_refs, audit_events, personal memory of other usersALL financial amounts OMITTED. ALL compensation fields OMITTED. ALL personal contact details beyond name+role OMITTED. spine_network_id OMITTED. promotion_id OMITTED.Session account scope only

11. Connector Extension Registry Table (Field Visibility by Role)

ConnectorCanonical EntityExtension FieldField TypeLabelRoles With Visibility
salesforcedealssalesforce.lead_sourcestringLead Sourcesales_rep, sales_manager, cro, founder
salesforcedealssalesforce.forecast_categorystringForecast Categorysales_manager, cro, founder
salesforcedealssalesforce.competitorstringCompetitorsales_manager, cro, founder
salesforcedealssalesforce.next_stepstringNext Stepsales_rep, sales_manager, cro, founder
salesforcecontactssalesforce.lead_statusstringLead Statussales_rep, sales_manager, cro
salesforcecontactssalesforce.mailing_citystringCitysales_rep, sales_manager, cro, founder
hubspotdealshubspot.hs_deal_stage_probabilitynumberStage Probabilitysales_manager, cro, founder
hubspotcontactshubspot.hs_lead_statusstringLead Statussales_rep, sales_manager, cro, founder
hubspotaccountshubspot.hs_analytics_sourcestringFirst Touch Sourcemarketing_manager, cmo, founder
stripeaccountsstripe.payment_method_fingerprintstringPayment Fingerprintfinance_director, founder
stripeinvoicesstripe.payment_intent_idstringPayment Intentfinance_director, founder
stripeaccountsstripe.customer_idstringStripe Customer IDsales, finance_director, founder
stripeaccountsstripe.subscription_statusstringSubscription Statussales, finance_director, founder
slackactivitiesslack.channel_idstringSlack Channelsales_rep, sales_manager, cro
slackactivitiesslack.thread_tsstringThread Timestampfounder, sales_rep, sales_manager, cro
lineartaskslinear.issue_idstringLinear Issue IDfounder, engineering_lead
lineartaskslinear.prioritynumberLinear Priorityfounder, engineering_lead
greenhousecontactsgreenhouse.candidate_stagestringCandidate Stagehr_manager, founder
greenhousecontactsgreenhouse.job_title_appliedstringApplied Rolehr_manager, founder
quickbookscontactsquickbooks.qb_invoice_idstringQB Invoice IDfinance_director, founder
quickbooksinvoicesquickbooks.vendor_typestringVendor Typefinance_director, founder

12. Execution Map — Schema Entity × Dev × Customer Zero × Product

Schema EntitySchema PageEntity TypeCanonical TableDev OwnerDev StatusDev Blocker / Next ActionCustomer Zero Status
tenants6Canonical Tablespine workerLive on main114-table Neon schema live on main as of Jul 27. FORTRESS_DATABASE_URL bound.Seed
users6Canonical Tablespine worker + Clerk auth moduleLive on mainClerk is canonical auth. Descope is dev fallback. work_lifecycle_stage field needs wiring to onboarding completion API.Seed
roles6Canonical Tablespine workerLive on mainSystem roles seeded in Neon fortress seed. Custom role creation UI pending.Seed
connector_catalog6Canonical Tableconnector worker + schema-ai workerLive on main64-connector catalog seeded Jul 28 with real logos. Vercel logo is 147-byte placeholder — needs real SVG asset.Seed
connector_installations6Canonical Tableconnector worker + integration-management-mcpLive on mainActivation endpoints live Jul 23. MCP pool scoped per tenant/user. OAuth release blocker resolved Jul 24.Seed
accounts6Canonical Tablespine worker + connector pipelineLive on mainTable live in Neon. Connector pipeline writes on sync. No UI blocker.Seed
contacts6Canonical Tablespine worker + connector pipelineLive on mainTable live. people domain projection active.Seed
deals6Canonical Tablespine worker + connector pipelineLive on mainTable live. Revenue domain projection active. Deal stage pipeline view rendered via canvas manifest.Seed
connector_extensions7Extension Patternconnector worker + schema-ai workerIn progressSidecar table schema defined. connector_extension_schemas table needs migration. Merge at projection time not yet wired into Projection Engine.Pending
connector_extension_schemas7Extension Patternschema-ai workerIn progressSchema-AI service born Jul 19. Manifest parsing logic in progress. connector_extension_schemas migration pending.Pending
connector_extension_registry7Extension Patternconnector workerPendingDepends on connector_extension_schemas migration. No blocker beyond sequencing.Pending
tasks6Canonical Tablespine worker + connector pipelineLive on mainTable live. project_management app_category wired. operations domain projection active.Seed
activities6Canonical Tablespine worker + connector pipelineLive on mainTable live. communication app_category wired. activities log projection active.Seed
signals6Canonical Tablepipeline workerLive on mainSignal workflow wiring is a P1 TODO in intelligence worker. Pipeline emits signals but SignalWorkflow not yet wired to downstream consumers.Seed
invoices6Canonical Tablespine worker + connector pipelinePendingBilling connector (Stripe) not installed for Customer Zero. Table migrated but empty.Pending
playbooks6Canonical Tablepipeline worker + workflow workerIn progressPlaybook table live. Supabase Realtime event forwarding TODO in workflow worker. Playbook execution wiring in progress.Pending
memory_items6Canonical Tablecontinuity worker + twin-orchestratorIn progressMorningBriefWorkflow wiring is P1 TODO in continuity worker. D1 brief storage TODO in intelligence worker. Personal and agent scopes partially wired.Pending
RBAC projection rules2Projection Rulespine worker + Projection Engine (gateway)In progressProjection Engine defined Jul 21 (architecture freeze). SharedWorkbench contract shipped. D1 audit_log persistence TODO in gateway. Cache invalidation logic in progress.Seed
canvas projection manifests3Canvas / UI Contractspine worker + cognitive workbench runtimeIn progressCognitive workbench runtime shipped Jul 23. Canvas manifest JSONB being rendered. System templates per role defined in schema. Tenant/user override merge not yet wired.Seed
canvas_overrides6Canonical Tablecognitive workbench runtime + tunerPendingTable migrated. Override merge logic depends on tuner_proposals pipeline. Not yet wired end-to-end.Pending
personal memory scope4Memory Scopecontinuity worker (Durable Objects per user_id)In progressDurable Objects wired. MorningBriefWorkflow P1 TODO. AI Search replacement P4 TODO.Pending
organizational memory scope4Memory Scopecontinuity worker (Postgres/D1 — append-only)PendingOrg memory scope table not yet migrated to Neon. Depends on continuity worker P1 completion.Pending
agent memory scope4Memory Scopetwin-orchestrator (Durable Objects per session)In progressTwin-orchestrator shipped. Wire to Act service in Phase 4 TODO. Session-scoped Durable Objects active.Seed
operational memory scope4Memory Scopegateway + KV cacheLive on mainKV hot cache live. Operational DB projection cache active. TTL and invalidation working.Seed
promotion_queue5Queue / Eventspine worker + continuity workerIn progressPromotion queue table live in Neon. Auto-promote logic for pipeline signals wired. Human approval review UI not yet built.Pending
teams6Canonical Tablespine workerPendingTable migrated. Team creation UI not built. Depends on Settings page expansion.Not applicable
team_members6Canonical Tablespine workerPendingDepends on teams table UI.Not applicable
approval_chains6Canonical Tablespine worker + gateway capability checkPendingapproval_chains table migrated. Capability check in gateway wired to RBAC. Custom chain definition UI not built.Not applicable
audit_log6Canonical Tablegateway workerIn progressD1 audit_log persistence is a TODO in gateway. Datadog/Splunk compliance integration TODO. Table migrated.Pending
retention_policies6Canonical Tablespine worker + continuity workerPendingTable migrated. Retention enforcement logic not built. No blocker beyond prioritisation.Not applicable
workbench_signals8Tuner / Feedbackcognitive workbench runtime (frontend → KV)PendingSignal emission from frontend not yet wired. Frontend success/error toasts TODO. Workbench runtime shipped but signal capture not implemented.Pending
tuner_proposals8Tuner / Feedbackschema-ai worker + cognitive workbench runtimePendingDepends on workbench_signals being wired. Tuner aggregation logic not built.Pending
Salesforce extension (deals)7Extension Patternconnector workerPendingSalesforce connector not installed for Customer Zero. Extension schema drafted in manifest format.Pending
HubSpot extension (contacts, accounts)7Extension Patternconnector workerIn progressHubSpot connector active for Customer Zero. Extension sidecar write not yet wired — connector writes to canonical tables only today.Pending
Linear extension (tasks)7Extension Patternconnector workerIn progressLinear connector active for Customer Zero. Extension sidecar write pending.Pending
Slack extension (activities)7Extension Patternconnector workerIn progressSlack connector active. Activity write wired. Extension sidecar (channel_id, thread_ts) pending.Pending
Marketplace catalog1Canvas / UI Contractconnector worker + apps/web (Cloudflare Pages)Live on main64-connector catalog live. Marketing CTAs wiring to marketplace flow complete Jul 27.Seed

13. Frontend Projection Contract

The frontend renderer receives a fully-hydrated canvas projection JSONB document and renders it. It makes no schema decisions. It has no hardcoded column names. It has no hardcoded role logic.

What the frontend receives per view load:

{
  "projection_key": "proj:sales_rep:revenue:acct_01J9:pipeline",
  "rendered_at": "2026-07-28T10:00:00Z",
  "ttl_seconds": 300,
  "user": {
    "user_id": "usr_01J9...",
    "role_slug": "sales_rep",
    "work_lifecycle_stage": "active"
  },
  "zones": [ ... ],
  "available_actions": [
    {"capability": "deal.update_stage", "label": "Update Stage", "approval_required": false},
    {"capability": "deal.log_activity", "label": "Log Activity", "approval_required": false},
    {"capability": "deal.request_discount", "label": "Request Discount", "approval_required": true}
  ],
  "pending_approvals": 2,
  "tuner_proposals_pending": 1
}

The frontend renders zones, surfaces available_actions, shows approval badges, and emits workbench_signals back. That is its entire contract with the backend.


14. Complete Frontend-to-Spine Loop

USER ACTION
  -> [READ] Workbench renders canvas projection
     Projection Engine: Spine → RBAC → canvas manifest → renderer
     < 50ms from Operational DB cache

  -> [WRITE] User edits a cell / triggers an action
     Capability check: approval_chains
     Human approval binds the exact proposal/version
     Governed Spine Writer commits through the Promotion Queue
     Signal emitted → pipeline → downstream playbooks

  -> [BEHAVE] User interacts with the canvas surface
     workbench_signals written (column_hidden, filter_applied, etc.)
     Tuner aggregates signals → tuner_proposals
     Proposals submitted to Promotion Queue
     Approved proposals write to canvas_overrides
     Projection Engine invalidates affected cache keys
     Next render uses updated canvas manifest

15. Schema Layer Index

LayerPageWhat it defines
Canonical tables06Every spine table, lifecycle stage, SQL shape
Connector extensions07How connectors extend entities without polluting canonical schema
RBAC projections02How roles filter entities and fields
Canvas manifests03How projections are laid out as JSONB for the renderer
Tuner08How the frontend feeds back into the spine
Memory04How observations accumulate
Promotion Queue05How memory becomes canonical truth
Entity domains01How app categories map to business domains