Skip to content

nova-advisor-sn-app schema

Reverse-engineered by reading the ServiceNow update-set export directly (dictionary + sys_db_object XML) rather than authored by the team that owns this app. Review, if needed, happens via PR against this file like any other schema change.

Derived from the ServiceNow update-set export in nova-advisor-sn-app (dictionary + sys_db_object XML under the 29c2be3cc35903d078485f73e401314d app folder, scope x_novaw_advisor, app name "Nova Advisor"). This is the current data contract for the Advisor app's ServiceNow-side tables.

The app's own README.md and CODEOWNERS carry no written description or dependency list (README is a bare title; CODEOWNERS just names three individual owners), so app-level context below is inferred entirely from the XML: script includes, REST API definitions, and scope privileges.

App dependencies (inferred from sys_scope_privilege and script includes, since no README/dependency doc exists): read access to the out-of-box Knowledge Management tables kb_knowledge and kb_knowledge_base, execute access to the OOB KBVersioning script include, and read access to x_novaw_platform_kb_base_type_m2m — a table owned by a separate app in the x_novaw_platform scope, not this one. That's a cross-app dependency to flag for the schema-first gate. Execute access to getDefaultDomain suggests the app also depends on the platform's domain-support utility.

The app ships three REST API definitions (no local tables of their own — they operate against this app's tables and/or the cross-scope Knowledge tables above): Advisor (sync_thread, sync_message, GET thread — looks like the sync surface an external agent backend would call to push thread/message state into ServiceNow), Kb Management API (article create/get/versions, manager add/remove, access summary, native-editor URL), and Nova Platform Knowledge API (owner update, access summary). Script includes present: AdvisorService/AdvisorServiceImpl, KbManagementService/KbManagementServiceImpl, KnowledgeArticleService, and PolicyService/PolicyServiceImpl. The Policy-related script includes and a Policy editor / Policy List UI widget pair exist in this scope, but no Policy table is defined in this app's dictionary — policy data apparently lives elsewhere (possibly the x_novaw_platform scope, given the x_novaw_platform_kb_base_type_m2m privilege) and is only surfaced here via script include + widget. See Open Questions.

Both tables in this app carry sys_domain (a plain domain_id dictionary field, plus a "Domain - Set Domain" before-insert/update business rule on each table) — this app is domain-separated (multi-tenant) throughout, even though it does not use the sys_domain_path companion field seen in some sibling apps.

Diagrams

erDiagram
    x_novaw_advisor_thread ||--o{ x_novaw_advisor_message : "has messages"
    x_novaw_advisor_thread }o--|| kb_knowledge : "grounded in (edge-encrypted ref, external table)"
    x_novaw_advisor_message }o--|| sys_user : "attributed to (external table)"

    x_novaw_advisor_thread {
        string title
        choice status
        string checkpoint_state
        reference kb_knowledge
        domain_id sys_domain
    }
    x_novaw_advisor_message {
        integer order
        string content
        choice role
        reference user
        reference thread
        glide_date_time sent_at
        string request_id
        domain_id sys_domain
    }

Tables at a glance

Table Label Purpose
x_novaw_advisor_thread Advisor Thread One row per advisor conversation/session — title, lifecycle status, an opaque checkpoint blob for resuming agent state, and an optional link to the Knowledge article the thread is grounded in or was spawned from.
x_novaw_advisor_message Advisor Message One row per message in a thread — ordered, attributed to user or assistant, with content, timestamp, and an external request_id for correlating with the calling system's own request/trace id.

Neither table extends a base ServiceNow table (super_class is empty on both sys_db_object records) — both are standalone custom tables.

Table detail

x_novaw_advisor_thread — Advisor Thread

Field Type Notes
title string(80) Not mandatory. No default.
status choice(40) Not mandatory. Default open. Choices: open (seq 0), closed (seq 1), archived (seq 2).
checkpoint_state string(32000) Not mandatory, not displayed. Large free-text blob — likely a serialized agent/checkpoint state (e.g. JSON) rather than user-facing text, given the size and display=false.
kb_knowledge reference → kb_knowledge (OOB Knowledge Management, external to this scope) Not mandatory. display=true (used as the record's display value). Attributes: edge_encryption_enabled=true, encode_utf8=false — this reference field is edge-encrypted.
sys_domain domain_id(40) Domain-separation field; set by a before-insert/update business rule ("Domain - Set Domain - Advisor Thread").

Indexed on kb_knowledge (index) and sys_domain (index2).

x_novaw_advisor_message — Advisor Message

Field Type Notes
order integer(40) Not mandatory. No default — presumably app-assigned sequence number within a thread.
content string(65535) Not mandatory. Max length suggests this is meant to hold full message bodies (effectively unbounded for chat purposes) despite being typed as plain string rather than journal/html.
role choice(40) Not mandatory, no default. Choices: user (seq 0), assistant (seq 1). No system role modeled.
user reference → sys_user Not mandatory. Who the message is attributed to (presumably populated for role=user; unclear who/what is set for role=assistant — see Open Questions).
thread reference → x_novaw_advisor_thread Not mandatory (dictionary-wise) — parent thread. Not mandatory is surprising for what looks like a required FK; see Open Questions.
sent_at glide_date_time(40) Not mandatory. No default — presumably app-set at message creation.
request_id string(80) Not mandatory. Likely a correlation id from the calling system (matches the sync_message REST operation), not a ServiceNow request record reference (it's a plain string, not a reference type).
sys_domain domain_id(40) Domain-separation field; set by a before-insert/update business rule ("Domain - Set Domain - Advisor Message").

Indexed on sys_domain (index), thread (index2), and user (index3).

Relationships (informal)

x_novaw_advisor_thread (1) ──< (many) x_novaw_advisor_message   [message.thread]
x_novaw_advisor_message (many) >── (1) sys_user                 [message.user]   (external/base table)
x_novaw_advisor_thread  (many) >── (1) kb_knowledge              [thread.kb_knowledge, edge-encrypted]  (external table, OOB Knowledge Mgmt)

Open questions / things to confirm before treating this as the reviewed contract

  1. No FK is mandatory. x_novaw_advisor_message.thread and .user, and x_novaw_advisor_thread.kb_knowledge, are all mandatory=false in the dictionary. For a message-in-a-thread model this is surprising — confirm whether thread is actually enforced as required at the application layer (script include / REST operation) rather than the dictionary, or whether orphan messages (no thread) are a real, intended case.
  2. content is typed string, not journal/html. Max length 65535 is generous but still a hard cap — confirm whether very long assistant responses (e.g. with tool-call transcripts) can exceed it, and whether any truncation/streaming behavior exists upstream.
  3. checkpoint_state (string, 32000, not displayed) has no documented shape. No sys_documentation help text exists for any field in this app (only column_labels were found) — the likely JSON/serialized structure of this blob is a guess, not confirmed.
  4. role choice list has no system value — only user/assistant. If the underlying agent uses system/tool-role messages, confirm how (or whether) those get persisted here at all.
  5. x_novaw_advisor_thread.kb_knowledge is edge-encryption-enabled (edge_encryption_enabled=true) — confirm this is intentional (i.e. the app is deployed in an edge-encryption-enabled instance) rather than a leftover/copy-paste attribute, since it's the only encrypted field in either table.
  6. Policy tables are missing. The scope ships PolicyService / PolicyServiceImpl script includes and "Policy editor" / "Policy List" Service Portal widgets, but no Policy table exists in this app's dictionary/ export. Either policy data lives in another app's scope (plausible given the x_novaw_platform_kb_base_type_m2m cross-scope read privilege) or the policy feature reads/writes tables not included in this update-set snapshot. Needs confirmation before drawing any policy-related ER diagram — this is also the schema most directly relevant to this repo's nova-policy-advisor Feature Set, so its schema-changes.md treats the Policy Editor's KB article model as net new rather than assuming it maps onto an existing table here.
  7. x_novaw_advisor_rest_user_agent ACL with no backing table. A sys_security_acl record named x_novaw_advisor_rest_user_agent exists, gated by roles x_novaw_advisor.user and x_novaw_advisor.api, but there is no corresponding sys_db_object/dictionary entry for that name in this export — it's very likely an ACL on a Scripted REST Resource/processor rather than a table, but that couldn't be confirmed from the files present (no sys_ws_operation or processor XML in the export uses that exact literal name).
  8. Three REST API surfaces, only two tables. "Kb Management API" and "Nova Platform Knowledge API" operate on kb_knowledge/kb_knowledge_base (owned outside this scope) rather than on x_novaw_advisor_thread/ x_novaw_advisor_message. Only the "Advisor" API (sync_thread, sync_message, GET thread) appears to touch this app's own two tables. Confirm whether Kb Management / Nova Platform Knowledge really belong in this app's scope at all, or are colocated here for delivery convenience.
  9. No sys_domain_path field on either table, unlike some sibling apps that pair sys_domain with sys_domain_path. Confirm whether that's a deliberate scoping choice (flat domain model) for this app.
  10. Read all dictionary/, sys_db_object, sys_documentation, sys_dictionary, sys_script_include, sys_ws_definition, sys_ws_operation, sys_scope_privilege, sys_security_acl*, sys_user_role, and sys_script (business rule) XML files present in the export for this document — no table, field, or cross-scope reference was knowingly omitted. The two tables above (x_novaw_advisor_thread, x_novaw_advisor_message) are the only ones this app defines in its own scope.