diff --git a/.github/workflows/full-docs-validation.yaml b/.github/workflows/full-docs-validation.yaml index 16014ac59..0d4f1a448 100644 --- a/.github/workflows/full-docs-validation.yaml +++ b/.github/workflows/full-docs-validation.yaml @@ -71,17 +71,18 @@ jobs: sudo apt-get update sudo apt-get install -y pandoc + - name: Test chatbot product map generator + run: python3 -m unittest discover -s site/scripts -p 'test_generate_chatbot_product_map.py' -v + - name: Verify chatbot product map is up to date run: | set -euo pipefail python3 site/scripts/generate_chatbot_product_map.py git diff --exit-code -- \ site/llm/chatbot-product-map.md \ + site/llm/chatbot-product-map-dropped.md \ site/llm/chatbot-product-map-frontend-snapshot.json - - name: Test chatbot product map generator - run: python3 -m unittest discover -s site/scripts -p 'test_generate_chatbot_product_map.py' -v - - name: Validate LLM markdown render run: bash llm/render.sh working-directory: site diff --git a/.github/workflows/validate-docs-site.yaml b/.github/workflows/validate-docs-site.yaml index 043b6423a..6e0fb21b1 100644 --- a/.github/workflows/validate-docs-site.yaml +++ b/.github/workflows/validate-docs-site.yaml @@ -382,6 +382,12 @@ jobs: sudo apt-get update sudo apt-get install -y pandoc + # Runs on every PR, targeted previews included, and before the map + # auto-commit below, so a guide edit that evicts a pinned related doc fails + # the PR that caused it. + - name: Test chatbot product map generator + run: python3 -m unittest discover -s site/scripts -p 'test_generate_chatbot_product_map.py' -v + # Targeted guide edits can change the map without requiring a full render. - name: Verify chatbot product map is up to date run: | @@ -390,7 +396,7 @@ jobs: map_changed=false snapshot_changed=false - git diff --quiet site/llm/chatbot-product-map.md || map_changed=true + git diff --quiet site/llm/chatbot-product-map.md site/llm/chatbot-product-map-dropped.md || map_changed=true git diff --quiet site/llm/chatbot-product-map-frontend-snapshot.json || snapshot_changed=true if [ "$map_changed" = false ] && [ "$snapshot_changed" = false ]; then @@ -399,25 +405,21 @@ jobs: fi if [ "$snapshot_changed" = true ]; then - echo "::error::Frontend snapshot is stale. Run: make -C site refresh-chatbot-product-map (requires ../frontend checkout), then commit site/llm/chatbot-product-map-frontend-snapshot.json and site/llm/chatbot-product-map.md." + echo "::error::Frontend snapshot is stale. Run: make -C site refresh-chatbot-product-map (requires ../frontend checkout), then commit site/llm/chatbot-product-map-frontend-snapshot.json, site/llm/chatbot-product-map.md and site/llm/chatbot-product-map-dropped.md." exit 1 fi if [ "${{ github.event.pull_request.head.repo.full_name }}" != "${{ github.repository }}" ]; then - echo "::error::chatbot-product-map.md is stale for this fork PR. Run: make -C site generate-chatbot-product-map, then commit site/llm/chatbot-product-map.md." + echo "::error::chatbot-product-map.md is stale for this fork PR. Run: make -C site generate-chatbot-product-map, then commit site/llm/chatbot-product-map.md and site/llm/chatbot-product-map-dropped.md." exit 1 fi git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" - git add site/llm/chatbot-product-map.md + git add site/llm/chatbot-product-map.md site/llm/chatbot-product-map-dropped.md git commit -m "chore: refresh chatbot product map" git push origin "HEAD:${{ github.head_ref }}" - echo "Auto-committed refreshed site/llm/chatbot-product-map.md." - - - name: Test chatbot product map generator - if: steps.preview.outputs.targeted != 'true' - run: python3 -m unittest discover -s site/scripts -p 'test_generate_chatbot_product_map.py' -v + echo "Auto-committed refreshed site/llm/chatbot-product-map.md and chatbot-product-map-dropped.md." - name: Validate LLM markdown render if: steps.preview.outputs.targeted != 'true' diff --git a/site/llm/README.md b/site/llm/README.md index f75d9ebef..ab3bbbbd8 100644 --- a/site/llm/README.md +++ b/site/llm/README.md @@ -36,6 +36,7 @@ Valerie needs routes in the product UI (especially **Settings**) mapped to docum |----------|---------| | `chatbot-product-map-frontend-snapshot.json` | Vendored extract from `validmind/frontend` (Settings tree, sidebar nav, `helpLink` / docs URLs) | | `chatbot-product-map.md` | Retrieval-oriented map: routes → primary/related docs + section headings from `.qmd` | +| `chatbot-product-map-dropped.md` | Related docs that matched a route but did not fit in its six slots. Committed for review only, not copied into the LLM corpus | ### Why a frontend snapshot? @@ -49,7 +50,9 @@ CI does **not** check out `validmind/frontend` (private repo; cross-repo PAT sco | Product routes or in-app help links | `make refresh-chatbot-product-map` (requires a sibling `../frontend` checkout) | Commit both `chatbot-product-map.md` and `chatbot-product-map-frontend-snapshot.json` when the snapshot changes. CI fails if either file is out of date after regeneration. -For same-repo pull requests, the validate workflow auto-commits docs-only refreshes of `chatbot-product-map.md`. Fork pull requests and any snapshot drift still fail and require a local regenerate + commit. +For same-repo pull requests, the validate workflow auto-commits docs-only refreshes of `chatbot-product-map.md` and `chatbot-product-map-dropped.md`. Fork pull requests and any snapshot drift still fail and require a local regenerate + commit. + +Related docs are ranked by section (the route's own docs section, then sections a route keyword names, then filename-only matches), then by position in the docs sidebars, then by path. Each route keeps six. A diff in `chatbot-product-map-dropped.md` means a route gained or lost a related doc, so check it when you add or reorder guide pages. Generator: `site/scripts/generate_chatbot_product_map.py` Tests: `python3 -m unittest discover -s site/scripts -p 'test_generate_chatbot_product_map.py' -v` (from repo root). diff --git a/site/llm/chatbot-product-map-dropped.md b/site/llm/chatbot-product-map-dropped.md new file mode 100644 index 000000000..bc3d9e403 --- /dev/null +++ b/site/llm/chatbot-product-map-dropped.md @@ -0,0 +1,250 @@ +# Related docs dropped from the chatbot product map + +> Auto-generated by `site/scripts/generate_chatbot_product_map.py`. Not part of the LLM corpus. +> Each route lists matching docs that did not fit in its 6 related-doc slots, +> most relevant first. A change here means a route gained or lost a related doc. + +## `/analytics` + +- `/guide/reporting/tracking-organization-activity.html` +- `/guide/reporting/view-record-activity.html` +- `/guide/reporting/view-settings-activity.html` +- `/guide/reporting/working-with-analytics.html` +- `/guide/reporting/view-report-data.html` +- `/guide/reporting/manage-custom-reports.html` +- `/guide/reporting/export-analytics.html` +- `/guide/reporting/generating-exports.html` +- `/guide/reporting/export-inventory.html` +- `/guide/reporting/export-documents.html` +- `/guide/reporting/export-artifacts.html` +- `/faq/faq-reporting.html` + +## `/settings/attestation-templates` + +- `/guide/templates/customize-document-templates.html` +- `/guide/templates/manage-document-templates.html` +- `/guide/templates/manage-text-block-library.html` +- `/guide/templates/managing-documents.html` +- `/guide/templates/manage-document-types.html` +- `/guide/templates/manage-documents.html` +- `/guide/templates/customize-document-checker.html` +- `/faq/faq-attestations.html` +- `/guide/risk-tiering/manage-risk-tier-templates.html` + +## `/settings/block-library` + +- `/guide/templates/customize-document-checker.html` +- `/guide/risk-tiering/manage-risk-tier-templates.html` + +## `/settings/document-types` + +- `/guide/templates/customize-document-checker.html` +- `/guide/risk-tiering/manage-risk-tier-templates.html` + +## `/settings/documents/general` + +- `/guide/templates/manage-documents.html` +- `/guide/templates/customize-document-checker.html` +- `/guide/risk-tiering/manage-risk-tier-templates.html` + +## `/settings/integrations/connections` + +- `/guide/integrations/configure-data-exports.html` +- `/guide/integrations/integrations-examples.html` +- `/guide/integrations/integrations-examples/create-jira-ticket.html` +- `/guide/integrations/integrations-examples/create-servicenow-incident.html` +- `/guide/integrations/integrations-examples/synchronize-aws-bedrock.html` +- `/guide/integrations/integrations-examples/synchronize-aws-sagemaker.html` +- `/guide/integrations/integrations-examples/synchronize-with-databricks.html` +- `/guide/integrations/integrations-examples/synchronize-gitlab.html` +- `/guide/integrations/integrations-examples/use-webhooks-with-workflows.html` +- `/faq/faq-integrations.html` + +## `/settings/integrations/data-exports` + +- `/guide/integrations/link-external-records.html` +- `/guide/integrations/integrations-examples.html` +- `/guide/integrations/integrations-examples/create-jira-ticket.html` +- `/guide/integrations/integrations-examples/create-servicenow-incident.html` +- `/guide/integrations/integrations-examples/synchronize-aws-bedrock.html` +- `/guide/integrations/integrations-examples/synchronize-aws-sagemaker.html` +- `/guide/integrations/integrations-examples/synchronize-with-databricks.html` +- `/guide/integrations/integrations-examples/synchronize-gitlab.html` +- `/guide/integrations/integrations-examples/use-webhooks-with-workflows.html` +- `/faq/faq-integrations.html` + +## `/settings/integrations/secrets` + +- `/guide/integrations/configure-data-exports.html` +- `/guide/integrations/integrations-examples.html` +- `/guide/integrations/integrations-examples/create-jira-ticket.html` +- `/guide/integrations/integrations-examples/create-servicenow-incident.html` +- `/guide/integrations/integrations-examples/synchronize-aws-bedrock.html` +- `/guide/integrations/integrations-examples/synchronize-aws-sagemaker.html` +- `/guide/integrations/integrations-examples/synchronize-with-databricks.html` +- `/guide/integrations/integrations-examples/synchronize-gitlab.html` +- `/guide/integrations/integrations-examples/use-webhooks-with-workflows.html` +- `/faq/faq-integrations.html` + +## `/settings/inventory-model-custom-fields` + +- `/guide/inventory/register-records-in-inventory.html` +- `/guide/inventory/import-records-into-inventory.html` +- `/guide/inventory/customize-inventory-layout.html` +- `/guide/inventory/edit-inventory-fields.html` +- `/guide/inventory/customize-record-overview-page.html` +- `/guide/inventory/manage-record-versions.html` +- `/guide/inventory/view-record-data.html` +- `/guide/inventory/managing-the-inventory.html` +- `/guide/inventory/configure-record-interdependencies.html` +- `/guide/inventory/archive-delete-records.html` +- `/faq/faq-inventory.html` +- `/guide/reporting/export-inventory.html` + +## `/settings/primary-record-type-stages` + +- `/guide/inventory/register-records-in-inventory.html` +- `/guide/inventory/import-records-into-inventory.html` +- `/guide/inventory/customize-inventory-layout.html` +- `/guide/inventory/edit-inventory-fields.html` +- `/guide/inventory/customize-record-overview-page.html` +- `/guide/inventory/manage-record-versions.html` +- `/guide/inventory/view-record-data.html` +- `/guide/inventory/managing-the-inventory.html` +- `/guide/inventory/configure-record-interdependencies.html` +- `/guide/inventory/archive-delete-records.html` +- `/faq/faq-inventory.html` +- `/guide/reporting/export-inventory.html` + +## `/settings/primary-record-types` + +- `/guide/inventory/register-records-in-inventory.html` +- `/guide/inventory/import-records-into-inventory.html` +- `/guide/inventory/customize-inventory-layout.html` +- `/guide/inventory/edit-inventory-fields.html` +- `/guide/inventory/customize-record-overview-page.html` +- `/guide/inventory/manage-record-versions.html` +- `/guide/inventory/view-record-data.html` +- `/guide/inventory/managing-the-inventory.html` +- `/guide/inventory/configure-record-interdependencies.html` +- `/guide/inventory/archive-delete-records.html` +- `/faq/faq-inventory.html` +- `/guide/reporting/export-inventory.html` + +## `/settings/primary-record-types/fields` + +- `/guide/inventory/register-records-in-inventory.html` +- `/guide/inventory/import-records-into-inventory.html` +- `/guide/inventory/customize-inventory-layout.html` +- `/guide/inventory/edit-inventory-fields.html` +- `/guide/inventory/customize-record-overview-page.html` +- `/guide/inventory/manage-record-versions.html` +- `/guide/inventory/view-record-data.html` +- `/guide/inventory/managing-the-inventory.html` +- `/guide/inventory/configure-record-interdependencies.html` +- `/guide/inventory/archive-delete-records.html` +- `/faq/faq-inventory.html` +- `/guide/reporting/export-inventory.html` + +## `/settings/risk-tier-templates` + +- `/guide/templates/customize-document-templates.html` +- `/guide/templates/manage-document-templates.html` +- `/guide/templates/manage-text-block-library.html` +- `/guide/templates/managing-documents.html` +- `/guide/templates/manage-document-types.html` +- `/guide/templates/manage-documents.html` +- `/guide/templates/customize-document-checker.html` + +## `/settings/segments` + +- `/guide/inventory/register-records-in-inventory.html` +- `/guide/inventory/import-records-into-inventory.html` +- `/guide/inventory/customize-inventory-layout.html` +- `/guide/inventory/edit-inventory-fields.html` +- `/guide/inventory/customize-record-overview-page.html` +- `/guide/inventory/manage-record-versions.html` +- `/guide/inventory/view-record-data.html` +- `/guide/inventory/managing-the-inventory.html` +- `/guide/inventory/configure-record-interdependencies.html` +- `/guide/inventory/archive-delete-records.html` +- `/faq/faq-inventory.html` +- `/guide/reporting/export-inventory.html` + +## `/settings/stakeholders` + +- `/guide/inventory/register-records-in-inventory.html` +- `/guide/inventory/import-records-into-inventory.html` +- `/guide/inventory/customize-inventory-layout.html` +- `/guide/inventory/edit-inventory-fields.html` +- `/guide/inventory/customize-record-overview-page.html` +- `/guide/inventory/manage-record-versions.html` +- `/guide/inventory/view-record-data.html` +- `/guide/inventory/managing-the-inventory.html` +- `/guide/inventory/configure-record-interdependencies.html` +- `/guide/inventory/archive-delete-records.html` +- `/faq/faq-inventory.html` +- `/guide/reporting/export-inventory.html` + +## `/settings/statuses` + +- `/guide/inventory/register-records-in-inventory.html` +- `/guide/inventory/import-records-into-inventory.html` +- `/guide/inventory/customize-inventory-layout.html` +- `/guide/inventory/edit-inventory-fields.html` +- `/guide/inventory/customize-record-overview-page.html` +- `/guide/inventory/manage-record-versions.html` +- `/guide/inventory/view-record-data.html` +- `/guide/inventory/managing-the-inventory.html` +- `/guide/inventory/configure-record-interdependencies.html` +- `/guide/inventory/archive-delete-records.html` +- `/faq/faq-inventory.html` +- `/guide/reporting/export-inventory.html` + +## `/settings/templates` + +- `/guide/templates/customize-document-checker.html` +- `/guide/risk-tiering/manage-risk-tier-templates.html` + +## `/settings/workflow-states` + +- `/guide/workflows/set-field-formulas.html` +- `/guide/workflows/working-with-workflows.html` +- `/guide/workflows/manage-workflows.html` +- `/guide/workflows/transition-workflows.html` +- `/guide/workflows/manage-workflow-tasks.html` +- `/guide/workflows/assign-workflow-executions.html` +- `/guide/workflows/workflow-configuration-examples.html` +- `/faq/faq-workflows.html` +- `/guide/integrations/integrations-examples/use-webhooks-with-workflows.html` +- `/guide/risk-tiering/set-up-risk-tiering-workflows.html` +- `/guide/monitoring/trigger-workflows-on-threshold-breach.html` + +## `/settings/workflows` + +- `/guide/workflows/set-field-formulas.html` +- `/guide/workflows/working-with-workflows.html` +- `/guide/workflows/manage-workflows.html` +- `/guide/workflows/transition-workflows.html` +- `/guide/workflows/manage-workflow-tasks.html` +- `/guide/workflows/assign-workflow-executions.html` +- `/guide/workflows/workflow-configuration-examples.html` +- `/faq/faq-workflows.html` +- `/guide/integrations/integrations-examples/use-webhooks-with-workflows.html` +- `/guide/risk-tiering/set-up-risk-tiering-workflows.html` +- `/guide/monitoring/trigger-workflows-on-threshold-breach.html` + +## `/workflows` + +- `/guide/workflows/configure-workflows.html` +- `/guide/workflows/set-field-formulas.html` +- `/guide/workflows/working-with-workflows.html` +- `/guide/workflows/manage-workflows.html` +- `/guide/workflows/transition-workflows.html` +- `/guide/workflows/manage-workflow-tasks.html` +- `/guide/workflows/assign-workflow-executions.html` +- `/guide/workflows/workflow-configuration-examples.html` +- `/faq/faq-workflows.html` +- `/guide/integrations/integrations-examples/use-webhooks-with-workflows.html` +- `/guide/risk-tiering/set-up-risk-tiering-workflows.html` +- `/guide/monitoring/trigger-workflows-on-threshold-breach.html` diff --git a/site/llm/chatbot-product-map.md b/site/llm/chatbot-product-map.md index 7dcde7aab..d44eef53d 100644 --- a/site/llm/chatbot-product-map.md +++ b/site/llm/chatbot-product-map.md @@ -21,18 +21,18 @@ **Docs (related):** -- `/faq/faq-attestations.html` - - Sections: Who can submit, review, and approve attestations?; Why aren't attestations displayed right after I create them?; Why are my attestations split into multiple submissions?; Can I schedule recurring attestation periods?; Can I start an attestation period in the past?; What happens when an attestation period starts?; What information is captured in an attestation snapshot?; Can I change an attestation after signing off? -- `/guide/attestation/approve-attestations.html` - - Sections: Prerequisites; Steps +- `/guide/attestation/working-with-attestations.html` + - Sections: Key concepts; Where do I access attestations?; How does the attestation process work?; How are attestation submissions organized?; How do I create meaningful attestation questionnaires?; Prerequisites; Manage attestations; What's next - `/guide/attestation/manage-attestations.html` - Sections: Prerequisites; Add attestation templates; Test attestation schedules; Edit attestation periods; Cancel attestation periods; View attestations dashboard; Progress; Responses +- `/guide/attestation/submit-attestations.html` + - Sections: Prerequisites; Steps - `/guide/attestation/review-attestations.html` - Sections: Prerequisites; Steps -- `/guide/attestation/submit-attestations.html` +- `/guide/attestation/approve-attestations.html` - Sections: Prerequisites; Steps -- `/guide/attestation/working-with-attestations.html` - - Sections: Key concepts; Where do I access attestations?; How does the attestation process work?; How are attestation submissions organized?; How do I create meaningful attestation questionnaires?; Prerequisites; Manage attestations; What's next +- `/guide/templates/working-with-document-templates.html` + - Sections: What's next - *No direct help link in frontend; related docs inferred from keywords.* @@ -48,16 +48,16 @@ **Docs (related):** -- `/faq/faq-attestations.html` - - Sections: Who can submit, review, and approve attestations?; Why aren't attestations displayed right after I create them?; Why are my attestations split into multiple submissions?; Can I schedule recurring attestation periods?; Can I start an attestation period in the past?; What happens when an attestation period starts?; What information is captured in an attestation snapshot?; Can I change an attestation after signing off? -- `/guide/attestation/approve-attestations.html` +- `/guide/attestation/working-with-attestations.html` + - Sections: Key concepts; Where do I access attestations?; How does the attestation process work?; How are attestation submissions organized?; How do I create meaningful attestation questionnaires?; Prerequisites; Manage attestations; What's next +- `/guide/attestation/submit-attestations.html` - Sections: Prerequisites; Steps - `/guide/attestation/review-attestations.html` - Sections: Prerequisites; Steps -- `/guide/attestation/submit-attestations.html` +- `/guide/attestation/approve-attestations.html` - Sections: Prerequisites; Steps -- `/guide/attestation/working-with-attestations.html` - - Sections: Key concepts; Where do I access attestations?; How does the attestation process work?; How are attestation submissions organized?; How do I create meaningful attestation questionnaires?; Prerequisites; Manage attestations; What's next +- `/faq/faq-attestations.html` + - Sections: Who can submit, review, and approve attestations?; Why aren't attestations displayed right after I create them?; Why are my attestations split into multiple submissions?; Can I schedule recurring attestation periods?; Can I start an attestation period in the past?; What happens when an attestation period starts?; What information is captured in an attestation snapshot?; Can I change an attestation after signing off? ### Organization @@ -84,14 +84,14 @@ **Docs (related):** -- `/guide/risk-tiering/manage-risk-tier-templates.html` - - Sections: Prerequisites; Access risk tier templates; Create a template; Select a tier calculation method; Define risk tier levels; Publish a template; Create a new version; Duplicate a template -- `/guide/templates/customize-document-checker.html` - - Sections: Prerequisites; Manage regulations and policies; Default regulations provided by } cannot be edited.; Archive, restore, or delete default regulations; Archiving and deleting apply to your organization only.; Manage assessments; Default assessments provided by } cannot be edited, only cloned.; Add or clone assessments +- `/guide/templates/working-with-document-templates.html` + - Sections: What's next - `/guide/templates/customize-document-templates.html` - Sections: Prerequisites; Edit template outlines; Configure assessment options[^4]; Edit YAML templates; Template schema; Troubleshooting YAML templates; Add text blocks to templates; Add text blocks via template outlines - `/guide/templates/manage-document-templates.html` - Sections: Prerequisites; View document templates; Create document templates; Edit document template outlines; Swap document templates; View currently applied templates; Swap between templates; Duplicate document templates +- `/guide/templates/managing-documents.html` + - Sections: Manage document defaults; Manage document types and documents; What's next - `/guide/templates/manage-document-types.html` - Sections: Prerequisites; Add document types; Edit or delete document types; Development, Validation, and Monitoring document types are stock types and cannot be deleted. - `/guide/templates/manage-documents.html` @@ -117,35 +117,35 @@ **Docs (related):** -- `/guide/risk-tiering/manage-risk-tier-templates.html` - - Sections: Prerequisites; Access risk tier templates; Create a template; Select a tier calculation method; Define risk tier levels; Publish a template; Create a new version; Duplicate a template -- `/guide/templates/customize-document-checker.html` - - Sections: Prerequisites; Manage regulations and policies; Default regulations provided by } cannot be edited.; Archive, restore, or delete default regulations; Archiving and deleting apply to your organization only.; Manage assessments; Default assessments provided by } cannot be edited, only cloned.; Add or clone assessments +- `/guide/templates/working-with-document-templates.html` + - Sections: What's next - `/guide/templates/customize-document-templates.html` - Sections: Prerequisites; Edit template outlines; Configure assessment options[^4]; Edit YAML templates; Template schema; Troubleshooting YAML templates; Add text blocks to templates; Add text blocks via template outlines - `/guide/templates/manage-document-templates.html` - Sections: Prerequisites; View document templates; Create document templates; Edit document template outlines; Swap document templates; View currently applied templates; Swap between templates; Duplicate document templates -- `/guide/templates/manage-documents.html` - - Sections: Prerequisites; Add record documents; PDF requirements and limits; How do I get the best results when converting PDFs into editable documents?; How can I trust that the conversion is accurate?; Troubleshooting; My PDF conversion is stuck. What can I do?; Edit record documents - `/guide/templates/manage-text-block-library.html` - Sections: Prerequisites; Add text blocks; Add existing text blocks to library; Duplicate text blocks; Edit text blocks; Delete text blocks +- `/guide/templates/managing-documents.html` + - Sections: Manage document defaults; Manage document types and documents; What's next +- `/guide/templates/manage-documents.html` + - Sections: Prerequisites; Add record documents; PDF requirements and limits; How do I get the best results when converting PDFs into editable documents?; How can I trust that the conversion is accurate?; Troubleshooting; My PDF conversion is stuck. What can I do?; Edit record documents #### `/settings/documents/general` — General **Docs (related):** -- `/guide/risk-tiering/manage-risk-tier-templates.html` - - Sections: Prerequisites; Access risk tier templates; Create a template; Select a tier calculation method; Define risk tier levels; Publish a template; Create a new version; Duplicate a template -- `/guide/templates/customize-document-checker.html` - - Sections: Prerequisites; Manage regulations and policies; Default regulations provided by } cannot be edited.; Archive, restore, or delete default regulations; Archiving and deleting apply to your organization only.; Manage assessments; Default assessments provided by } cannot be edited, only cloned.; Add or clone assessments +- `/guide/templates/working-with-document-templates.html` + - Sections: What's next - `/guide/templates/customize-document-templates.html` - Sections: Prerequisites; Edit template outlines; Configure assessment options[^4]; Edit YAML templates; Template schema; Troubleshooting YAML templates; Add text blocks to templates; Add text blocks via template outlines - `/guide/templates/manage-document-templates.html` - Sections: Prerequisites; View document templates; Create document templates; Edit document template outlines; Swap document templates; View currently applied templates; Swap between templates; Duplicate document templates +- `/guide/templates/manage-text-block-library.html` + - Sections: Prerequisites; Add text blocks; Add existing text blocks to library; Duplicate text blocks; Edit text blocks; Delete text blocks +- `/guide/templates/managing-documents.html` + - Sections: Manage document defaults; Manage document types and documents; What's next - `/guide/templates/manage-document-types.html` - Sections: Prerequisites; Add document types; Edit or delete document types; Development, Validation, and Monitoring document types are stock types and cannot be deleted. -- `/guide/templates/manage-documents.html` - - Sections: Prerequisites; Add record documents; PDF requirements and limits; How do I get the best results when converting PDFs into editable documents?; How can I trust that the conversion is accurate?; Troubleshooting; My PDF conversion is stuck. What can I do?; Edit record documents - *No direct help link in frontend; related docs inferred from keywords.* @@ -253,18 +253,18 @@ **Docs (related):** -- `/guide/configuration/configure-aws-privatelink.html` - - Sections: Prerequisites; VPC service information; Steps; What's next -- `/guide/configuration/configure-azure-private-link.html` - - Sections: Prerequisites; VNet service information; Steps; What's next -- `/guide/configuration/configure-google-private-service-connect.html` - - Sections: Prerequisites; VPC service information; Configure your Google Cloud Platform project; Request access from }; Prepare your network for connection; Create an endpoint to connect to }; Steps; Create an endpoint to connect to the } authentication service -- `/guide/configuration/configure-sso-with-entra.html` - - Sections: Prerequisites; Step 1: Register an application in Entra ID; Step 2: Configure the claims Entra ID sends to ValidMind; Step 3: Send ValidMind your application details; Step 4: Map Entra groups to ValidMind roles; Step 5: Test sign-in; Why no client secret?; What's next -- `/guide/configuration/configuring-private-connectivity.html` - - Sections: What's next -- `/guide/configuration/customize-your-dashboard.html` - - Sections: Prerequisites; Manage dashboards; Add dashboards; Edit or remove dashboards; Share a dashboard with your organization; Manage widgets; Arrange widgets; Add widgets +- `/guide/integrations/configure-connections.html` + - Sections: Supported connections; Jira; ServiceNow; Amazon SageMaker; Amazon Bedrock; MLflow; GitLab; Databricks +- `/guide/integrations/managing-integrations.html` + - Sections: Key concepts; What can I do with integrations?; Analytics and reporting; Inventory; Workflows; Public REST API; Testing & documentation; Service integrations +- `/guide/integrations/manage-secrets.html` + - Sections: Prerequisites; Integration secrets; View integration secret details; Add or edit integration secrets; Add integration secrets; Edit integration secrets; Revoke or delete integration secrets; Revoke integration secrets +- `/guide/integrations/manage-service-accounts.html` + - Sections: Prerequisites; View service accounts; Create service accounts; Verify service account clients; How do I request an access token?; Disable or enable service accounts; Disable service accounts; Enable service accounts +- `/guide/integrations/implement-custom-integrations.html` + - Sections: How do custom integrations work?; Prerequisites; Reference API; Required endpoints; Optional endpoints; `/models` response format; Authentication; Code examples +- `/guide/integrations/link-external-records.html` + - Sections: Prerequisites; Link records; Refresh record data; Edit record links; Remove record links - *No direct help link in frontend; related docs inferred from keywords.* @@ -272,18 +272,18 @@ **Docs (related):** -- `/guide/configuration/configure-aws-privatelink.html` - - Sections: Prerequisites; VPC service information; Steps; What's next -- `/guide/configuration/configure-azure-private-link.html` - - Sections: Prerequisites; VNet service information; Steps; What's next -- `/guide/configuration/configure-google-private-service-connect.html` - - Sections: Prerequisites; VPC service information; Configure your Google Cloud Platform project; Request access from }; Prepare your network for connection; Create an endpoint to connect to }; Steps; Create an endpoint to connect to the } authentication service -- `/guide/configuration/configure-sso-with-entra.html` - - Sections: Prerequisites; Step 1: Register an application in Entra ID; Step 2: Configure the claims Entra ID sends to ValidMind; Step 3: Send ValidMind your application details; Step 4: Map Entra groups to ValidMind roles; Step 5: Test sign-in; Why no client secret?; What's next -- `/guide/configuration/configuring-private-connectivity.html` - - Sections: What's next -- `/guide/configuration/customize-your-dashboard.html` - - Sections: Prerequisites; Manage dashboards; Add dashboards; Edit or remove dashboards; Share a dashboard with your organization; Manage widgets; Arrange widgets; Add widgets +- `/guide/integrations/configure-data-exports.html` + - Sections: Prerequisites; View data exports; View export details; View export run history; Create data exports; Manage data exports; Edit exports; Disable or enable exports +- `/guide/integrations/managing-integrations.html` + - Sections: Key concepts; What can I do with integrations?; Analytics and reporting; Inventory; Workflows; Public REST API; Testing & documentation; Service integrations +- `/guide/integrations/manage-secrets.html` + - Sections: Prerequisites; Integration secrets; View integration secret details; Add or edit integration secrets; Add integration secrets; Edit integration secrets; Revoke or delete integration secrets; Revoke integration secrets +- `/guide/integrations/manage-service-accounts.html` + - Sections: Prerequisites; View service accounts; Create service accounts; Verify service account clients; How do I request an access token?; Disable or enable service accounts; Disable service accounts; Enable service accounts +- `/guide/integrations/configure-connections.html` + - Sections: Supported connections; Jira; ServiceNow; Amazon SageMaker; Amazon Bedrock; MLflow; GitLab; Databricks +- `/guide/integrations/implement-custom-integrations.html` + - Sections: How do custom integrations work?; Prerequisites; Reference API; Required endpoints; Optional endpoints; `/models` response format; Authentication; Code examples - *No direct help link in frontend; related docs inferred from keywords.* @@ -291,18 +291,18 @@ **Docs (related):** -- `/guide/configuration/configure-aws-privatelink.html` - - Sections: Prerequisites; VPC service information; Steps; What's next -- `/guide/configuration/configure-azure-private-link.html` - - Sections: Prerequisites; VNet service information; Steps; What's next -- `/guide/configuration/configure-google-private-service-connect.html` - - Sections: Prerequisites; VPC service information; Configure your Google Cloud Platform project; Request access from }; Prepare your network for connection; Create an endpoint to connect to }; Steps; Create an endpoint to connect to the } authentication service -- `/guide/configuration/configure-sso-with-entra.html` - - Sections: Prerequisites; Step 1: Register an application in Entra ID; Step 2: Configure the claims Entra ID sends to ValidMind; Step 3: Send ValidMind your application details; Step 4: Map Entra groups to ValidMind roles; Step 5: Test sign-in; Why no client secret?; What's next -- `/guide/configuration/configuring-private-connectivity.html` - - Sections: What's next -- `/guide/configuration/customize-your-dashboard.html` - - Sections: Prerequisites; Manage dashboards; Add dashboards; Edit or remove dashboards; Share a dashboard with your organization; Manage widgets; Arrange widgets; Add widgets +- `/guide/integrations/manage-secrets.html` + - Sections: Prerequisites; Integration secrets; View integration secret details; Add or edit integration secrets; Add integration secrets; Edit integration secrets; Revoke or delete integration secrets; Revoke integration secrets +- `/guide/integrations/managing-integrations.html` + - Sections: Key concepts; What can I do with integrations?; Analytics and reporting; Inventory; Workflows; Public REST API; Testing & documentation; Service integrations +- `/guide/integrations/manage-service-accounts.html` + - Sections: Prerequisites; View service accounts; Create service accounts; Verify service account clients; How do I request an access token?; Disable or enable service accounts; Disable service accounts; Enable service accounts +- `/guide/integrations/configure-connections.html` + - Sections: Supported connections; Jira; ServiceNow; Amazon SageMaker; Amazon Bedrock; MLflow; GitLab; Databricks +- `/guide/integrations/implement-custom-integrations.html` + - Sections: How do custom integrations work?; Prerequisites; Reference API; Required endpoints; Optional endpoints; `/models` response format; Authentication; Code examples +- `/guide/integrations/link-external-records.html` + - Sections: Prerequisites; Link records; Refresh record data; Edit record links; Remove record links - *No direct help link in frontend; related docs inferred from keywords.* @@ -312,18 +312,18 @@ **Docs (related):** -- `/faq/faq-inventory.html` - - Sections: How do I register records with }?; Can submitters register records before the final inventory type is known?; Are registration questionnaires customizable?; Can the } inventory be customized?; Can I archive or delete records within }?; Can I track interdependencies within the inventory?; Learn more -- `/guide/inventory/archive-delete-records.html` - - Sections: By default, only the Customer Admin role[^1] can access archived records.; Prerequisites; Change record stages; Instead of manually modifying your records' stages,[^4] we recommend manipulating stages via customized workflows.[^5]; Delete records; Record deletion is also permanent and cannot be undone. -- `/guide/inventory/configure-record-interdependencies.html` - - Sections: Prerequisites; View interdependencies; View dependencies across the inventory; Edit interdependencies; Define dependency types -- `/guide/inventory/customize-inventory-layout.html` - - Sections: Prerequisites; Swap between views; Customize table view; Manage custom inventory views -- `/guide/inventory/customize-record-overview-page.html` - - Sections: Prerequisites; Organize, show, or hide record fields; Highlight inventory record fields; Manage record field layouts; Manage personal record field layouts; Manage organization record field layouts -- `/guide/inventory/edit-inventory-fields.html` - - Sections: Prerequisites; Edit fields on individual records; Manage inventory record stakeholders; Insert field variables into a Long Text field; Manage attachments on records; Edit fields in bulk for multiple records +- `/guide/inventory/setting-up-the-inventory.html` + - Sections: What's next +- `/guide/inventory/manage-inventory-record-types.html` + - Sections: Prerequisites; Add or edit record types; Flag a type for Record Intake; Enable or disable record types +- `/guide/inventory/manage-inventory-fields.html` + - Sections: Prerequisites; Inventory field types; View, search, and filter inventory fields; Add or edit inventory fields; Insert field variables into a Long Text template; Recalculate calculated and aggregation fields; Rename custom field keys; Set the order of registration fields +- `/guide/inventory/manage-inventory-segments.html` + - Sections: Prerequisites; Key concepts; Add segments; Define segment conditions; How do I create effective filters?; Publish segments; Edit segments; Unpublish, archive, or delete segments +- `/guide/inventory/record-intake.html` + - Sections: Availability; Prerequisites; Flag an inventory record type for intake; Only one intake type; Register Intake records; Documents and artifacts after conversion; Configure an Intake classification workflow; Automated routing vs Manual review +- `/guide/inventory/working-with-the-inventory.html` + - Sections: Prerequisites; Search, filter, and sort records; How do I create effective filters?; Filter from a table cell; Filter by calculated and aggregation fields; Group records; Using the } inventory; What's next - *No direct help link in frontend; related docs inferred from keywords.* @@ -374,35 +374,35 @@ **Docs (related):** -- `/faq/faq-inventory.html` - - Sections: How do I register records with }?; Can submitters register records before the final inventory type is known?; Are registration questionnaires customizable?; Can the } inventory be customized?; Can I archive or delete records within }?; Can I track interdependencies within the inventory?; Learn more -- `/guide/inventory/archive-delete-records.html` - - Sections: By default, only the Customer Admin role[^1] can access archived records.; Prerequisites; Change record stages; Instead of manually modifying your records' stages,[^4] we recommend manipulating stages via customized workflows.[^5]; Delete records; Record deletion is also permanent and cannot be undone. -- `/guide/inventory/configure-record-interdependencies.html` - - Sections: Prerequisites; View interdependencies; View dependencies across the inventory; Edit interdependencies; Define dependency types -- `/guide/inventory/customize-inventory-layout.html` - - Sections: Prerequisites; Swap between views; Customize table view; Manage custom inventory views -- `/guide/inventory/customize-record-overview-page.html` - - Sections: Prerequisites; Organize, show, or hide record fields; Highlight inventory record fields; Manage record field layouts; Manage personal record field layouts; Manage organization record field layouts -- `/guide/inventory/edit-inventory-fields.html` - - Sections: Prerequisites; Edit fields on individual records; Manage inventory record stakeholders; Insert field variables into a Long Text field; Manage attachments on records; Edit fields in bulk for multiple records +- `/guide/inventory/setting-up-the-inventory.html` + - Sections: What's next +- `/guide/inventory/manage-inventory-record-types.html` + - Sections: Prerequisites; Add or edit record types; Flag a type for Record Intake; Enable or disable record types +- `/guide/inventory/manage-inventory-fields.html` + - Sections: Prerequisites; Inventory field types; View, search, and filter inventory fields; Add or edit inventory fields; Insert field variables into a Long Text template; Recalculate calculated and aggregation fields; Rename custom field keys; Set the order of registration fields +- `/guide/inventory/manage-inventory-segments.html` + - Sections: Prerequisites; Key concepts; Add segments; Define segment conditions; How do I create effective filters?; Publish segments; Edit segments; Unpublish, archive, or delete segments +- `/guide/inventory/record-intake.html` + - Sections: Availability; Prerequisites; Flag an inventory record type for intake; Only one intake type; Register Intake records; Documents and artifacts after conversion; Configure an Intake classification workflow; Automated routing vs Manual review +- `/guide/inventory/working-with-the-inventory.html` + - Sections: Prerequisites; Search, filter, and sort records; How do I create effective filters?; Filter from a table cell; Filter by calculated and aggregation fields; Group records; Using the } inventory; What's next #### `/settings/primary-record-types` — Inventory Record Types **Docs (related):** -- `/faq/faq-inventory.html` - - Sections: How do I register records with }?; Can submitters register records before the final inventory type is known?; Are registration questionnaires customizable?; Can the } inventory be customized?; Can I archive or delete records within }?; Can I track interdependencies within the inventory?; Learn more -- `/guide/inventory/archive-delete-records.html` - - Sections: By default, only the Customer Admin role[^1] can access archived records.; Prerequisites; Change record stages; Instead of manually modifying your records' stages,[^4] we recommend manipulating stages via customized workflows.[^5]; Delete records; Record deletion is also permanent and cannot be undone. -- `/guide/inventory/configure-record-interdependencies.html` - - Sections: Prerequisites; View interdependencies; View dependencies across the inventory; Edit interdependencies; Define dependency types -- `/guide/inventory/customize-inventory-layout.html` - - Sections: Prerequisites; Swap between views; Customize table view; Manage custom inventory views -- `/guide/inventory/customize-record-overview-page.html` - - Sections: Prerequisites; Organize, show, or hide record fields; Highlight inventory record fields; Manage record field layouts; Manage personal record field layouts; Manage organization record field layouts -- `/guide/inventory/edit-inventory-fields.html` - - Sections: Prerequisites; Edit fields on individual records; Manage inventory record stakeholders; Insert field variables into a Long Text field; Manage attachments on records; Edit fields in bulk for multiple records +- `/guide/inventory/setting-up-the-inventory.html` + - Sections: What's next +- `/guide/inventory/manage-inventory-record-types.html` + - Sections: Prerequisites; Add or edit record types; Flag a type for Record Intake; Enable or disable record types +- `/guide/inventory/manage-inventory-fields.html` + - Sections: Prerequisites; Inventory field types; View, search, and filter inventory fields; Add or edit inventory fields; Insert field variables into a Long Text template; Recalculate calculated and aggregation fields; Rename custom field keys; Set the order of registration fields +- `/guide/inventory/manage-inventory-segments.html` + - Sections: Prerequisites; Key concepts; Add segments; Define segment conditions; How do I create effective filters?; Publish segments; Edit segments; Unpublish, archive, or delete segments +- `/guide/inventory/record-intake.html` + - Sections: Availability; Prerequisites; Flag an inventory record type for intake; Only one intake type; Register Intake records; Documents and artifacts after conversion; Configure an Intake classification workflow; Automated routing vs Manual review +- `/guide/inventory/working-with-the-inventory.html` + - Sections: Prerequisites; Search, filter, and sort records; How do I create effective filters?; Filter from a table cell; Filter by calculated and aggregation fields; Group records; Using the } inventory; What's next - *No direct help link in frontend; related docs inferred from keywords.* @@ -410,18 +410,18 @@ **Docs (related):** -- `/faq/faq-inventory.html` - - Sections: How do I register records with }?; Can submitters register records before the final inventory type is known?; Are registration questionnaires customizable?; Can the } inventory be customized?; Can I archive or delete records within }?; Can I track interdependencies within the inventory?; Learn more -- `/guide/inventory/archive-delete-records.html` - - Sections: By default, only the Customer Admin role[^1] can access archived records.; Prerequisites; Change record stages; Instead of manually modifying your records' stages,[^4] we recommend manipulating stages via customized workflows.[^5]; Delete records; Record deletion is also permanent and cannot be undone. -- `/guide/inventory/configure-record-interdependencies.html` - - Sections: Prerequisites; View interdependencies; View dependencies across the inventory; Edit interdependencies; Define dependency types -- `/guide/inventory/customize-inventory-layout.html` - - Sections: Prerequisites; Swap between views; Customize table view; Manage custom inventory views -- `/guide/inventory/customize-record-overview-page.html` - - Sections: Prerequisites; Organize, show, or hide record fields; Highlight inventory record fields; Manage record field layouts; Manage personal record field layouts; Manage organization record field layouts -- `/guide/inventory/edit-inventory-fields.html` - - Sections: Prerequisites; Edit fields on individual records; Manage inventory record stakeholders; Insert field variables into a Long Text field; Manage attachments on records; Edit fields in bulk for multiple records +- `/guide/inventory/setting-up-the-inventory.html` + - Sections: What's next +- `/guide/inventory/manage-inventory-record-types.html` + - Sections: Prerequisites; Add or edit record types; Flag a type for Record Intake; Enable or disable record types +- `/guide/inventory/manage-inventory-fields.html` + - Sections: Prerequisites; Inventory field types; View, search, and filter inventory fields; Add or edit inventory fields; Insert field variables into a Long Text template; Recalculate calculated and aggregation fields; Rename custom field keys; Set the order of registration fields +- `/guide/inventory/manage-inventory-segments.html` + - Sections: Prerequisites; Key concepts; Add segments; Define segment conditions; How do I create effective filters?; Publish segments; Edit segments; Unpublish, archive, or delete segments +- `/guide/inventory/record-intake.html` + - Sections: Availability; Prerequisites; Flag an inventory record type for intake; Only one intake type; Register Intake records; Documents and artifacts after conversion; Configure an Intake classification workflow; Automated routing vs Manual review +- `/guide/inventory/working-with-the-inventory.html` + - Sections: Prerequisites; Search, filter, and sort records; How do I create effective filters?; Filter from a table cell; Filter by calculated and aggregation fields; Group records; Using the } inventory; What's next - *No direct help link in frontend; related docs inferred from keywords.* @@ -464,24 +464,37 @@ #### `/settings/risk-tier-stages` — Risk Tier Stages -- *No direct help link; content may be covered under scattered guide sections.* +**Docs (related):** + +- `/guide/risk-tiering/working-with-risk-tiering.html` + - Sections: Overview; Key concepts; Lifecycle; Who does what; Where to access risk tiering; What's next +- `/guide/risk-tiering/manage-risk-tier-templates.html` + - Sections: Prerequisites; Access risk tier templates; Create a template; Select a tier calculation method; Define risk tier levels; Publish a template; Create a new version; Duplicate a template +- `/guide/risk-tiering/configure-risk-tier-calculation.html` + - Sections: Prerequisites; Set up a Scorecard template; 1. Configure scoring levels; 2. Add risk factors; 3. Add components and scoring rules; 4. Set risk tier thresholds; 5. Configure override rules; Set up a Risk Matrix template +- `/guide/risk-tiering/manage-risk-tier-assessments.html` + - Sections: Prerequisites; Access risk tier assessments; Create an assessment; Review factor scores; Risk Factors; Factor Score Breakdown; Risk Tier Thresholds; Tier Assignment Rules +- `/guide/risk-tiering/set-up-risk-tiering-workflows.html` + - Sections: Prerequisites; About risk tiering workflows; Define governance stages; Add a risk tiering workflow; Configure risk tiering steps; Track governance on the assessment or template; How governance runs behave; What's next + +- *No direct help link in frontend; related docs inferred from keywords.* #### `/settings/risk-tier-templates` — Risk Tier Templates **Docs (related):** +- `/guide/risk-tiering/working-with-risk-tiering.html` + - Sections: Overview; Key concepts; Lifecycle; Who does what; Where to access risk tiering; What's next - `/guide/risk-tiering/manage-risk-tier-templates.html` - Sections: Prerequisites; Access risk tier templates; Create a template; Select a tier calculation method; Define risk tier levels; Publish a template; Create a new version; Duplicate a template -- `/guide/templates/customize-document-checker.html` - - Sections: Prerequisites; Manage regulations and policies; Default regulations provided by } cannot be edited.; Archive, restore, or delete default regulations; Archiving and deleting apply to your organization only.; Manage assessments; Default assessments provided by } cannot be edited, only cloned.; Add or clone assessments -- `/guide/templates/customize-document-templates.html` - - Sections: Prerequisites; Edit template outlines; Configure assessment options[^4]; Edit YAML templates; Template schema; Troubleshooting YAML templates; Add text blocks to templates; Add text blocks via template outlines -- `/guide/templates/manage-document-templates.html` - - Sections: Prerequisites; View document templates; Create document templates; Edit document template outlines; Swap document templates; View currently applied templates; Swap between templates; Duplicate document templates -- `/guide/templates/manage-document-types.html` - - Sections: Prerequisites; Add document types; Edit or delete document types; Development, Validation, and Monitoring document types are stock types and cannot be deleted. -- `/guide/templates/manage-documents.html` - - Sections: Prerequisites; Add record documents; PDF requirements and limits; How do I get the best results when converting PDFs into editable documents?; How can I trust that the conversion is accurate?; Troubleshooting; My PDF conversion is stuck. What can I do?; Edit record documents +- `/guide/risk-tiering/configure-risk-tier-calculation.html` + - Sections: Prerequisites; Set up a Scorecard template; 1. Configure scoring levels; 2. Add risk factors; 3. Add components and scoring rules; 4. Set risk tier thresholds; 5. Configure override rules; Set up a Risk Matrix template +- `/guide/risk-tiering/manage-risk-tier-assessments.html` + - Sections: Prerequisites; Access risk tier assessments; Create an assessment; Review factor scores; Risk Factors; Factor Score Breakdown; Risk Tier Thresholds; Tier Assignment Rules +- `/guide/risk-tiering/set-up-risk-tiering-workflows.html` + - Sections: Prerequisites; About risk tiering workflows; Define governance stages; Add a risk tiering workflow; Configure risk tiering steps; Track governance on the assessment or template; How governance runs behave; What's next +- `/guide/templates/working-with-document-templates.html` + - Sections: What's next - *No direct help link in frontend; related docs inferred from keywords.* @@ -509,16 +522,16 @@ - `/guide/inventory/manage-inventory-segments.html` - Sections: Prerequisites; Key concepts; Add segments; Define segment conditions; How do I create effective filters?; Publish segments; Edit segments; Unpublish, archive, or delete segments -- `/faq/faq-inventory.html` - - Sections: How do I register records with }?; Can submitters register records before the final inventory type is known?; Are registration questionnaires customizable?; Can the } inventory be customized?; Can I archive or delete records within }?; Can I track interdependencies within the inventory?; Learn more -- `/guide/inventory/archive-delete-records.html` - - Sections: By default, only the Customer Admin role[^1] can access archived records.; Prerequisites; Change record stages; Instead of manually modifying your records' stages,[^4] we recommend manipulating stages via customized workflows.[^5]; Delete records; Record deletion is also permanent and cannot be undone. -- `/guide/inventory/configure-record-interdependencies.html` - - Sections: Prerequisites; View interdependencies; View dependencies across the inventory; Edit interdependencies; Define dependency types -- `/guide/inventory/customize-inventory-layout.html` - - Sections: Prerequisites; Swap between views; Customize table view; Manage custom inventory views -- `/guide/inventory/customize-record-overview-page.html` - - Sections: Prerequisites; Organize, show, or hide record fields; Highlight inventory record fields; Manage record field layouts; Manage personal record field layouts; Manage organization record field layouts +- `/guide/inventory/setting-up-the-inventory.html` + - Sections: What's next +- `/guide/inventory/manage-inventory-record-types.html` + - Sections: Prerequisites; Add or edit record types; Flag a type for Record Intake; Enable or disable record types +- `/guide/inventory/manage-inventory-fields.html` + - Sections: Prerequisites; Inventory field types; View, search, and filter inventory fields; Add or edit inventory fields; Insert field variables into a Long Text template; Recalculate calculated and aggregation fields; Rename custom field keys; Set the order of registration fields +- `/guide/inventory/record-intake.html` + - Sections: Availability; Prerequisites; Flag an inventory record type for intake; Only one intake type; Register Intake records; Documents and artifacts after conversion; Configure an Intake classification workflow; Automated routing vs Manual review +- `/guide/inventory/working-with-the-inventory.html` + - Sections: Prerequisites; Search, filter, and sort records; How do I create effective filters?; Filter from a table cell; Filter by calculated and aggregation fields; Group records; Using the } inventory; What's next - *No direct help link in frontend; related docs inferred from keywords.* @@ -531,18 +544,18 @@ **Docs (related):** -- `/faq/faq-inventory.html` - - Sections: How do I register records with }?; Can submitters register records before the final inventory type is known?; Are registration questionnaires customizable?; Can the } inventory be customized?; Can I archive or delete records within }?; Can I track interdependencies within the inventory?; Learn more -- `/guide/inventory/archive-delete-records.html` - - Sections: By default, only the Customer Admin role[^1] can access archived records.; Prerequisites; Change record stages; Instead of manually modifying your records' stages,[^4] we recommend manipulating stages via customized workflows.[^5]; Delete records; Record deletion is also permanent and cannot be undone. -- `/guide/inventory/configure-record-interdependencies.html` - - Sections: Prerequisites; View interdependencies; View dependencies across the inventory; Edit interdependencies; Define dependency types -- `/guide/inventory/customize-inventory-layout.html` - - Sections: Prerequisites; Swap between views; Customize table view; Manage custom inventory views -- `/guide/inventory/customize-record-overview-page.html` - - Sections: Prerequisites; Organize, show, or hide record fields; Highlight inventory record fields; Manage record field layouts; Manage personal record field layouts; Manage organization record field layouts -- `/guide/inventory/edit-inventory-fields.html` - - Sections: Prerequisites; Edit fields on individual records; Manage inventory record stakeholders; Insert field variables into a Long Text field; Manage attachments on records; Edit fields in bulk for multiple records +- `/guide/inventory/setting-up-the-inventory.html` + - Sections: What's next +- `/guide/inventory/manage-inventory-record-types.html` + - Sections: Prerequisites; Add or edit record types; Flag a type for Record Intake; Enable or disable record types +- `/guide/inventory/manage-inventory-fields.html` + - Sections: Prerequisites; Inventory field types; View, search, and filter inventory fields; Add or edit inventory fields; Insert field variables into a Long Text template; Recalculate calculated and aggregation fields; Rename custom field keys; Set the order of registration fields +- `/guide/inventory/manage-inventory-segments.html` + - Sections: Prerequisites; Key concepts; Add segments; Define segment conditions; How do I create effective filters?; Publish segments; Edit segments; Unpublish, archive, or delete segments +- `/guide/inventory/record-intake.html` + - Sections: Availability; Prerequisites; Flag an inventory record type for intake; Only one intake type; Register Intake records; Documents and artifacts after conversion; Configure an Intake classification workflow; Automated routing vs Manual review +- `/guide/inventory/working-with-the-inventory.html` + - Sections: Prerequisites; Search, filter, and sort records; How do I create effective filters?; Filter from a table cell; Filter by calculated and aggregation fields; Group records; Using the } inventory; What's next #### `/settings/statuses` — Model Stages @@ -553,18 +566,18 @@ **Docs (related):** -- `/faq/faq-inventory.html` - - Sections: How do I register records with }?; Can submitters register records before the final inventory type is known?; Are registration questionnaires customizable?; Can the } inventory be customized?; Can I archive or delete records within }?; Can I track interdependencies within the inventory?; Learn more -- `/guide/inventory/archive-delete-records.html` - - Sections: By default, only the Customer Admin role[^1] can access archived records.; Prerequisites; Change record stages; Instead of manually modifying your records' stages,[^4] we recommend manipulating stages via customized workflows.[^5]; Delete records; Record deletion is also permanent and cannot be undone. -- `/guide/inventory/configure-record-interdependencies.html` - - Sections: Prerequisites; View interdependencies; View dependencies across the inventory; Edit interdependencies; Define dependency types -- `/guide/inventory/customize-inventory-layout.html` - - Sections: Prerequisites; Swap between views; Customize table view; Manage custom inventory views -- `/guide/inventory/customize-record-overview-page.html` - - Sections: Prerequisites; Organize, show, or hide record fields; Highlight inventory record fields; Manage record field layouts; Manage personal record field layouts; Manage organization record field layouts -- `/guide/inventory/edit-inventory-fields.html` - - Sections: Prerequisites; Edit fields on individual records; Manage inventory record stakeholders; Insert field variables into a Long Text field; Manage attachments on records; Edit fields in bulk for multiple records +- `/guide/inventory/setting-up-the-inventory.html` + - Sections: What's next +- `/guide/inventory/manage-inventory-record-types.html` + - Sections: Prerequisites; Add or edit record types; Flag a type for Record Intake; Enable or disable record types +- `/guide/inventory/manage-inventory-fields.html` + - Sections: Prerequisites; Inventory field types; View, search, and filter inventory fields; Add or edit inventory fields; Insert field variables into a Long Text template; Recalculate calculated and aggregation fields; Rename custom field keys; Set the order of registration fields +- `/guide/inventory/manage-inventory-segments.html` + - Sections: Prerequisites; Key concepts; Add segments; Define segment conditions; How do I create effective filters?; Publish segments; Edit segments; Unpublish, archive, or delete segments +- `/guide/inventory/record-intake.html` + - Sections: Availability; Prerequisites; Flag an inventory record type for intake; Only one intake type; Register Intake records; Documents and artifacts after conversion; Configure an Intake classification workflow; Automated routing vs Manual review +- `/guide/inventory/working-with-the-inventory.html` + - Sections: Prerequisites; Search, filter, and sort records; How do I create effective filters?; Filter from a table cell; Filter by calculated and aggregation fields; Group records; Using the } inventory; What's next ### Documents @@ -577,18 +590,18 @@ **Docs (related):** -- `/guide/risk-tiering/manage-risk-tier-templates.html` - - Sections: Prerequisites; Access risk tier templates; Create a template; Select a tier calculation method; Define risk tier levels; Publish a template; Create a new version; Duplicate a template -- `/guide/templates/customize-document-checker.html` - - Sections: Prerequisites; Manage regulations and policies; Default regulations provided by } cannot be edited.; Archive, restore, or delete default regulations; Archiving and deleting apply to your organization only.; Manage assessments; Default assessments provided by } cannot be edited, only cloned.; Add or clone assessments +- `/guide/templates/working-with-document-templates.html` + - Sections: What's next - `/guide/templates/manage-document-templates.html` - Sections: Prerequisites; View document templates; Create document templates; Edit document template outlines; Swap document templates; View currently applied templates; Swap between templates; Duplicate document templates +- `/guide/templates/manage-text-block-library.html` + - Sections: Prerequisites; Add text blocks; Add existing text blocks to library; Duplicate text blocks; Edit text blocks; Delete text blocks +- `/guide/templates/managing-documents.html` + - Sections: Manage document defaults; Manage document types and documents; What's next - `/guide/templates/manage-document-types.html` - Sections: Prerequisites; Add document types; Edit or delete document types; Development, Validation, and Monitoring document types are stock types and cannot be deleted. - `/guide/templates/manage-documents.html` - Sections: Prerequisites; Add record documents; PDF requirements and limits; How do I get the best results when converting PDFs into editable documents?; How can I trust that the conversion is accurate?; Troubleshooting; My PDF conversion is stuck. What can I do?; Edit record documents -- `/guide/templates/manage-text-block-library.html` - - Sections: Prerequisites; Add text blocks; Add existing text blocks to library; Duplicate text blocks; Edit text blocks; Delete text blocks ### Organization @@ -623,18 +636,17 @@ **Docs (related):** -- `/faq/faq-workflows.html` - - Sections: Can I customize workflows within }?; What record stages are available for use in workflows?; Can we work with disconnected workflows?; You can also leverage the } once you are ready to document a specific record (model) for review and validation.; Learn more -- `/guide/integrations/integrations-examples/use-webhooks-with-workflows.html` - - Sections: Prerequisites; Start a workflow via webhook; 1. Configure workflow in }; 2. Start workflow from external system; Trigger a paused workflow to continue; 1. Configure workflow in }; 2. Trigger workflow to continue from external system -- `/guide/monitoring/trigger-workflows-on-threshold-breach.html` - - Sections: Prerequisites; Set up the trigger; When the workflow starts; Review the breach that started a workflow; Include breach details in an artifact or a notification; What a breach sends; What's next -- `/guide/risk-tiering/set-up-risk-tiering-workflows.html` - - Sections: Prerequisites; About risk tiering workflows; Define governance stages; Add a risk tiering workflow; Configure risk tiering steps; Track governance on the assessment or template; How governance runs behave; What's next -- `/guide/workflows/assign-workflow-executions.html` - - Sections: Prerequisites; Assign or change a workflow assignee; When starting or rescheduling a workflow; On scheduled, active, or waiting workflows; View workflows by assignee; Filter workflows by assignee; Export workflows by assignee +- `/guide/workflows/introduction-to-workflows.html` + - Sections: Workflow elements; What's next +- `/guide/workflows/workflow-step-types.html` - `/guide/workflows/conditional-step-requirements.html` - Sections: Prerequisites; Configure conditional requirements +- `/guide/workflows/setting-up-workflows.html` + - Sections: View, sort, and filter workflows; Search workflows; Sort workflows; Filter workflows; How do I create effective filters?; View workflow details; Review workflow properties; Browse version history +- `/guide/workflows/manage-record-stages.html` + - Sections: Prerequisites; Add record stages; Edit or delete record stages +- `/guide/workflows/configure-workflows.html` + - Sections: Prerequisites; Create custom workflows; 1. Add new workflows; 2. Configure workflow steps; 3. Link workflow together; Workflow steps relationship unclear on your canvas?; 4. Publish workflow; Clone existing workflows #### `/settings/workflows` — Workflows @@ -645,18 +657,17 @@ **Docs (related):** -- `/faq/faq-workflows.html` - - Sections: Can I customize workflows within }?; What record stages are available for use in workflows?; Can we work with disconnected workflows?; You can also leverage the } once you are ready to document a specific record (model) for review and validation.; Learn more -- `/guide/integrations/integrations-examples/use-webhooks-with-workflows.html` - - Sections: Prerequisites; Start a workflow via webhook; 1. Configure workflow in }; 2. Start workflow from external system; Trigger a paused workflow to continue; 1. Configure workflow in }; 2. Trigger workflow to continue from external system -- `/guide/monitoring/trigger-workflows-on-threshold-breach.html` - - Sections: Prerequisites; Set up the trigger; When the workflow starts; Review the breach that started a workflow; Include breach details in an artifact or a notification; What a breach sends; What's next -- `/guide/risk-tiering/set-up-risk-tiering-workflows.html` - - Sections: Prerequisites; About risk tiering workflows; Define governance stages; Add a risk tiering workflow; Configure risk tiering steps; Track governance on the assessment or template; How governance runs behave; What's next -- `/guide/workflows/assign-workflow-executions.html` - - Sections: Prerequisites; Assign or change a workflow assignee; When starting or rescheduling a workflow; On scheduled, active, or waiting workflows; View workflows by assignee; Filter workflows by assignee; Export workflows by assignee +- `/guide/workflows/introduction-to-workflows.html` + - Sections: Workflow elements; What's next +- `/guide/workflows/workflow-step-types.html` - `/guide/workflows/conditional-step-requirements.html` - Sections: Prerequisites; Configure conditional requirements +- `/guide/workflows/workflow-states.html` + - Sections: Prerequisites; Manage workflow states +- `/guide/workflows/manage-record-stages.html` + - Sections: Prerequisites; Add record stages; Edit or delete record stages +- `/guide/workflows/configure-workflows.html` + - Sections: Prerequisites; Create custom workflows; 1. Add new workflows; 2. Configure workflow steps; 3. Link workflow together; Workflow steps relationship unclear on your canvas?; 4. Publish workflow; Clone existing workflows ## Main application @@ -701,18 +712,18 @@ **Docs (related):** -- `/guide/monitoring/enable-monitoring.html` - - Sections: Prerequisites; Steps; 1. Get monitoring code snippet; 2. Select monitoring template; 3. Run code snippet; A template must already be applied to your selected document to populate monitoring test results in the }.; What's next - `/guide/monitoring/ongoing-monitoring.html` - Sections: Monitoring scenarios; Ongoing monitoring plan; Key concepts; Design and implementation; Testing; Manage ongoing monitoring; Code samples; } Available tests +- `/guide/monitoring/enable-monitoring.html` + - Sections: Prerequisites; Steps; 1. Get monitoring code snippet; 2. Select monitoring template; 3. Run code snippet; A template must already be applied to your selected document to populate monitoring test results in the }.; What's next - `/guide/monitoring/review-monitoring-results.html` - Sections: Prerequisites; Steps; Example monitoring test results; [} Satisfactory]; [} Requires Attention] +- `/guide/monitoring/work-with-metrics-over-time.html` + - Sections: **Log metrics over time }**; Prerequisites; Add metrics over time; Add integration metrics; Use the global time range; View metric over time metadata - `/guide/monitoring/set-thresholds-and-alerts.html` - Sections: Prerequisites; Use a custom function; Set the `passed` parameter; Output examples; Alert notifications - `/guide/monitoring/trigger-workflows-on-threshold-breach.html` - Sections: Prerequisites; Set up the trigger; When the workflow starts; Review the breach that started a workflow; Include breach details in an artifact or a notification; What a breach sends; What's next -- `/guide/monitoring/work-with-metrics-over-time.html` - - Sections: **Log metrics over time }**; Prerequisites; Add metrics over time; Add integration metrics; Use the global time range; View metric over time metadata - *No direct help link in frontend; related docs inferred from keywords.* @@ -739,18 +750,18 @@ **Docs (related):** -- `/faq/faq-attestations.html` - - Sections: Who can submit, review, and approve attestations?; Why aren't attestations displayed right after I create them?; Why are my attestations split into multiple submissions?; Can I schedule recurring attestation periods?; Can I start an attestation period in the past?; What happens when an attestation period starts?; What information is captured in an attestation snapshot?; Can I change an attestation after signing off? -- `/guide/attestation/approve-attestations.html` - - Sections: Prerequisites; Steps +- `/guide/attestation/working-with-attestations.html` + - Sections: Key concepts; Where do I access attestations?; How does the attestation process work?; How are attestation submissions organized?; How do I create meaningful attestation questionnaires?; Prerequisites; Manage attestations; What's next - `/guide/attestation/manage-attestations.html` - Sections: Prerequisites; Add attestation templates; Test attestation schedules; Edit attestation periods; Cancel attestation periods; View attestations dashboard; Progress; Responses +- `/guide/attestation/submit-attestations.html` + - Sections: Prerequisites; Steps - `/guide/attestation/review-attestations.html` - Sections: Prerequisites; Steps -- `/guide/attestation/submit-attestations.html` +- `/guide/attestation/approve-attestations.html` - Sections: Prerequisites; Steps -- `/guide/attestation/working-with-attestations.html` - - Sections: Key concepts; Where do I access attestations?; How does the attestation process work?; How are attestation submissions organized?; How do I create meaningful attestation questionnaires?; Prerequisites; Manage attestations; What's next +- `/faq/faq-attestations.html` + - Sections: Who can submit, review, and approve attestations?; Why aren't attestations displayed right after I create them?; Why are my attestations split into multiple submissions?; Can I schedule recurring attestation periods?; Can I start an attestation period in the past?; What happens when an attestation period starts?; What information is captured in an attestation snapshot?; Can I change an attestation after signing off? - *No direct help link in frontend; related docs inferred from keywords.* @@ -782,18 +793,17 @@ **Docs (related):** -- `/faq/faq-workflows.html` - - Sections: Can I customize workflows within }?; What record stages are available for use in workflows?; Can we work with disconnected workflows?; You can also leverage the } once you are ready to document a specific record (model) for review and validation.; Learn more -- `/guide/integrations/integrations-examples/use-webhooks-with-workflows.html` - - Sections: Prerequisites; Start a workflow via webhook; 1. Configure workflow in }; 2. Start workflow from external system; Trigger a paused workflow to continue; 1. Configure workflow in }; 2. Trigger workflow to continue from external system -- `/guide/monitoring/trigger-workflows-on-threshold-breach.html` - - Sections: Prerequisites; Set up the trigger; When the workflow starts; Review the breach that started a workflow; Include breach details in an artifact or a notification; What a breach sends; What's next -- `/guide/risk-tiering/set-up-risk-tiering-workflows.html` - - Sections: Prerequisites; About risk tiering workflows; Define governance stages; Add a risk tiering workflow; Configure risk tiering steps; Track governance on the assessment or template; How governance runs behave; What's next -- `/guide/workflows/assign-workflow-executions.html` - - Sections: Prerequisites; Assign or change a workflow assignee; When starting or rescheduling a workflow; On scheduled, active, or waiting workflows; View workflows by assignee; Filter workflows by assignee; Export workflows by assignee +- `/guide/workflows/introduction-to-workflows.html` + - Sections: Workflow elements; What's next +- `/guide/workflows/workflow-step-types.html` - `/guide/workflows/conditional-step-requirements.html` - Sections: Prerequisites; Configure conditional requirements +- `/guide/workflows/workflow-states.html` + - Sections: Prerequisites; Manage workflow states +- `/guide/workflows/setting-up-workflows.html` + - Sections: View, sort, and filter workflows; Search workflows; Sort workflows; Filter workflows; How do I create effective filters?; View workflow details; Review workflow properties; Browse version history +- `/guide/workflows/manage-record-stages.html` + - Sections: Prerequisites; Add record stages; Edit or delete record stages - *No direct help link in frontend; related docs inferred from keywords.* diff --git a/site/scripts/generate_chatbot_product_map.py b/site/scripts/generate_chatbot_product_map.py index c85dba307..560b8aac2 100644 --- a/site/scripts/generate_chatbot_product_map.py +++ b/site/scripts/generate_chatbot_product_map.py @@ -108,7 +108,13 @@ "groups": ["configuration/manage-groups", "configuration/managing-users"], "users": ["configuration/managing-users", "configuration/manage-users"], "invitation": ["configuration/managing-users", "configuration/manage-users"], - "integrations": ["integrations", "configuration"], + # Integrations settings screens map to /guide/integrations/ only. Pairing it + # with "configuration" let the longer segment win on specificity, so these + # screens listed organization setup pages and none of their own guides. + "integrations": ["integrations"], + "connections": ["integrations/configure-connections"], + "secrets": ["integrations/manage-secrets"], + "data-exports": ["integrations/configure-data-exports"], "templates": ["templates", "model-documentation"], "document": ["templates", "model-documentation"], "inventory": ["inventory", "model-inventory"], @@ -129,6 +135,7 @@ "attestation": ["attestation"], "regulation": ["templates/customize-virtual-document-validator", "model-validation"], "risk": ["model-validation/manage-validation-guidelines"], + "tier": ["risk-tiering"], "authentication": ["configuration/managing-your-organization"], "organization": ["configuration/managing-your-organization"], "profile": ["configuration/manage-your-profile", "configuration/personalizing-validmind"], @@ -395,8 +402,84 @@ def is_user_facing_doc(path: str) -> bool: return path.startswith(RELATED_DOC_PREFIXES) -def suggest_related_docs(route: ProductRoute, all_doc_paths: list[str]) -> list[DocRef]: - """Suggest related documentation based on route/title keywords.""" +# Maximum related docs listed per route in the map. +RELATED_DOCS_CAP = 6 + +# Rank tiers for related-doc candidates (lower sorts first). +TIER_SAME_SECTION = 0 # same directory as one of the route's primary docs +TIER_KEYWORD_SECTION = 1 # keyword names the doc's section, e.g. /guide/workflows/ +TIER_FILENAME_ONLY = 2 # keyword appears only in the filename of another section + +SIDEBAR_PAGE_PATTERN = re.compile( + r"""^\s*(?:-\s+)?(?:file:\s*)?["']?([\w./-]+\.(?:qmd|ipynb|md))["']?\s*$""" +) + + +def load_sidebar_order(site_dir: Path) -> dict[str, int]: + """Return {doc URL path: position} from the docs site sidebars. + + Docs writers order each sidebar section by hand (overview first, then + how-tos), so this position breaks ties between related docs in the same + tier before falling back to path order. Commented-out entries are skipped + and the first occurrence of a page wins. + """ + sources = [site_dir / "_quarto.yml", *sorted(site_dir.glob("*/_sidebar.yaml"))] + order: dict[str, int] = {} + for source in sources: + if not source.is_file(): + continue + for line in source.read_text(encoding="utf-8").splitlines(): + if line.lstrip().startswith("#"): + continue + match = SIDEBAR_PAGE_PATTERN.match(line) + if not match: + continue + rel = match.group(1) + url = "/" + rel.rsplit(".", 1)[0] + ".html" + order.setdefault(url, len(order)) + return order + + +def _doc_dir(path: str) -> str: + """Return the directory of a doc URL path with a trailing slash.""" + return path.rsplit("/", 1)[0] + "/" + + +def _related_doc_rank( + doc_path: str, segments: set[str], primary_dirs: set[str] +) -> tuple[int, int] | None: + """Return (tier, specificity) for a candidate, or None when no keyword matches.""" + inner = doc_path.lower() + matched = [seg for seg in segments if seg in inner] + if not matched: + return None + # A doc matched by a longer, more specific keyword segment outranks one + # matched only by a broad segment within the same tier. + specificity = max(len(seg) for seg in matched) + doc_dir = _doc_dir(inner) + if doc_dir in primary_dirs: + return TIER_SAME_SECTION, specificity + # Segments with a slash name a section explicitly (configuration/manage-roles); + # otherwise the keyword must appear in the directory, not just the filename. + if any("/" in seg or seg in doc_dir for seg in matched): + return TIER_KEYWORD_SECTION, specificity + return TIER_FILENAME_ONLY, specificity + + +def rank_related_docs( + route: ProductRoute, + all_doc_paths: list[str], + sidebar_order: dict[str, int] | None = None, +) -> list[DocRef]: + """Return every related-doc candidate for a route, most relevant first. + + Candidates are ordered by section first (the primary docs' own section, then + sections named by a route keyword, then filename-only matches elsewhere), then + by keyword specificity, then by position in the docs sidebar (pages missing + from the sidebar come last), then by path so the order is deterministic. + """ + sidebar_order = sidebar_order or {} + unlisted = len(sidebar_order) haystack = f"{route.path} {route.label} {route.group or ''}".lower() segments: set[str] = set() for keyword, doc_segments in RELATED_DOC_KEYWORDS.items(): @@ -404,18 +487,72 @@ def suggest_related_docs(route: ProductRoute, all_doc_paths: list[str]) -> list[ segments.update(doc_segments) primary_paths = {d.path for d in route.primary_docs} - related: list[tuple[int, DocRef]] = [] + primary_dirs = {_doc_dir(p.lower()) for p in primary_paths} + ranked: list[tuple[int, int, int, str]] = [] for doc_path in all_doc_paths: if doc_path in primary_paths or not is_user_facing_doc(doc_path): continue - inner = doc_path.lower() - # A doc matched by a longer, more specific keyword segment outranks one - # matched only by a broad segment, so it survives the cap below. - best = max((len(seg) for seg in segments if seg in inner), default=0) - if best: - related.append((best, DocRef(path=doc_path))) - related.sort(key=lambda item: (-item[0], item[1].path)) - return [ref for _, ref in related[:6]] + rank = _related_doc_rank(doc_path, segments, primary_dirs) + if rank is not None: + tier, specificity = rank + position = sidebar_order.get(doc_path, unlisted) + ranked.append((tier, -specificity, position, doc_path)) + ranked.sort() + return [DocRef(path=doc_path) for *_, doc_path in ranked] + + +def split_related_docs( + route: ProductRoute, + all_doc_paths: list[str], + sidebar_order: dict[str, int] | None = None, +) -> tuple[list[DocRef], list[DocRef]]: + """Return (kept, dropped) related docs for a route under RELATED_DOCS_CAP.""" + ranked = rank_related_docs(route, all_doc_paths, sidebar_order) + return ranked[:RELATED_DOCS_CAP], ranked[RELATED_DOCS_CAP:] + + +def suggest_related_docs( + route: ProductRoute, + all_doc_paths: list[str], + sidebar_order: dict[str, int] | None = None, +) -> list[DocRef]: + """Suggest related documentation based on route/title keywords.""" + kept, _ = split_related_docs(route, all_doc_paths, sidebar_order) + return kept + + +DROPPED_REPORT_SUFFIX = "-dropped.md" + + +def dropped_report_path(map_path: Path) -> Path: + """Return the sidecar path that lists related docs the cap left out.""" + return map_path.with_name(map_path.stem + DROPPED_REPORT_SUFFIX) + + +def format_dropped_report(dropped: dict[str, list[str]]) -> str: + """Render the related docs that the cap left out, one section per route. + + The file is committed next to the map so a new eviction shows up as a diff + during review. It is not copied into the LLM corpus. + """ + lines = [ + "# Related docs dropped from the chatbot product map", + "", + "> Auto-generated by `site/scripts/generate_chatbot_product_map.py`. Not part of the LLM corpus.", + f"> Each route lists matching docs that did not fit in its {RELATED_DOCS_CAP} related-doc slots,", + "> most relevant first. A change here means a route gained or lost a related doc.", + "", + ] + if not dropped: + lines.append("No routes drop related docs.") + lines.append("") + return "\n".join(lines) + for route_path in sorted(dropped): + lines.append(f"## `{route_path}`") + lines.append("") + lines.extend(f"- `{doc_path}`" for doc_path in dropped[route_path]) + lines.append("") + return "\n".join(lines) DEFAULT_SNAPSHOT_NAME = "chatbot-product-map-frontend-snapshot.json" @@ -567,7 +704,10 @@ def render_markdown( site_dir: Path, all_doc_paths: list[str], llm_output_dir: Path | None, + dropped_related: dict[str, list[str]] | None = None, ) -> str: + """Render the map. Related docs left out by the cap go into dropped_related.""" + sidebar_order = load_sidebar_order(site_dir) lines = [ "# ValidMind product-to-documentation map", "", @@ -600,7 +740,7 @@ def render_section(title: str, section_routes: list[ProductRoute]) -> None: lines.append(f"#### `{route.path}` — {route.label}") lines.append("") if not route.primary_docs: - related = suggest_related_docs(route, all_doc_paths) + related = suggest_related_docs(route, all_doc_paths, sidebar_order) if related: route.related_docs = related route.notes.append( @@ -616,14 +756,13 @@ def render_section(title: str, section_routes: list[ProductRoute]) -> None: for ref in route.primary_docs: lines.append(format_doc_line(ref, site_dir, llm_output_dir)) lines.append("") - related = route.related_docs or suggest_related_docs(route, all_doc_paths) - # Exclude primary from related - primary_keys = {d.path for d in route.primary_docs} - related = [r for r in related if r.path not in primary_keys] + related, dropped = split_related_docs(route, all_doc_paths, sidebar_order) + if dropped and dropped_related is not None: + dropped_related[route.path] = [ref.path for ref in dropped] if related: lines.append("**Docs (related):**") lines.append("") - for ref in related[:6]: + for ref in related: lines.append(format_doc_line(ref, site_dir, llm_output_dir)) lines.append("") for note in route.notes: @@ -709,10 +848,20 @@ def main() -> int: routes = merge_routes(settings, nav, file_links) all_doc_paths = collect_all_doc_qmd_paths(site_dir) - md = render_markdown(routes, site_dir, all_doc_paths, llm_output if llm_output.is_dir() else None) + dropped_related: dict[str, list[str]] = {} + md = render_markdown( + routes, + site_dir, + all_doc_paths, + llm_output if llm_output.is_dir() else None, + dropped_related, + ) output_path.parent.mkdir(parents=True, exist_ok=True) output_path.write_text(md, encoding="utf-8") print(f"Wrote {output_path} ({len(routes)} routes)") + dropped_path = dropped_report_path(output_path) + dropped_path.write_text(format_dropped_report(dropped_related), encoding="utf-8") + print(f"Wrote {dropped_path} ({len(dropped_related)} routes drop related docs)") if args.json_output: payload = { diff --git a/site/scripts/test_generate_chatbot_product_map.py b/site/scripts/test_generate_chatbot_product_map.py index 97f93ffda..514025837 100644 --- a/site/scripts/test_generate_chatbot_product_map.py +++ b/site/scripts/test_generate_chatbot_product_map.py @@ -80,6 +80,192 @@ def test_suggest_related_docs_ranks_specific_matches_first(self) -> None: related[0].path, "/guide/inventory/manage-inventory-segments.html" ) + def test_same_section_docs_outrank_cross_section_filename_matches(self) -> None: + route = gen.ProductRoute( + path="/settings/workflows", + label="Workflows", + group="Governance", + primary_docs=[gen.DocRef(path="/guide/workflows/setting-up-workflows.html")], + ) + all_paths = [ + "/faq/faq-workflows.html", + "/guide/integrations/integrations-examples/use-webhooks-with-workflows.html", + "/guide/risk-tiering/set-up-risk-tiering-workflows.html", + "/guide/workflows/manage-record-stages.html", + "/guide/workflows/setting-up-workflows.html", + "/guide/workflows/workflow-states.html", + ] + related = [r.path for r in gen.rank_related_docs(route, all_paths)] + self.assertEqual( + related[:2], + [ + "/guide/workflows/manage-record-stages.html", + "/guide/workflows/workflow-states.html", + ], + ) + self.assertNotIn("/guide/workflows/setting-up-workflows.html", related) + self.assertEqual( + related[2:], + [ + "/faq/faq-workflows.html", + "/guide/integrations/integrations-examples/use-webhooks-with-workflows.html", + "/guide/risk-tiering/set-up-risk-tiering-workflows.html", + ], + ) + + def test_keyword_section_outranks_filename_match_without_primary_docs(self) -> None: + route = gen.ProductRoute(path="/workflows", label="Workflows") + all_paths = [ + "/guide/risk-tiering/set-up-risk-tiering-workflows.html", + "/guide/workflows/manage-record-stages.html", + ] + related = [r.path for r in gen.rank_related_docs(route, all_paths)] + self.assertEqual( + related, + [ + "/guide/workflows/manage-record-stages.html", + "/guide/risk-tiering/set-up-risk-tiering-workflows.html", + ], + ) + + def test_drop_report_lists_evicted_paths(self) -> None: + route = gen.ProductRoute(path="/workflows", label="Workflows") + section = [f"/guide/workflows/page-{i}.html" for i in range(gen.RELATED_DOCS_CAP)] + outside = "/guide/risk-tiering/set-up-risk-tiering-workflows.html" + kept, dropped = gen.split_related_docs(route, section + [outside]) + self.assertEqual([r.path for r in kept], section) + self.assertEqual([r.path for r in dropped], [outside]) + + site = Path(__file__).resolve().parents[1] + dropped_related: dict[str, list[str]] = {} + md = gen.render_markdown( + {route.path: route}, site, section + [outside], None, dropped_related + ) + self.assertNotIn(outside, md) + self.assertEqual(dropped_related, {"/workflows": [outside]}) + report = gen.format_dropped_report(dropped_related) + self.assertIn("## `/workflows`", report) + self.assertIn(f"- `{outside}`", report) + self.assertIn("No routes drop related docs.", gen.format_dropped_report({})) + self.assertEqual( + gen.dropped_report_path(site / "llm" / "chatbot-product-map.md"), + site / "llm" / "chatbot-product-map-dropped.md", + ) + + def test_load_sidebar_order_follows_sidebar_and_skips_comments(self) -> None: + import tempfile + + with tempfile.TemporaryDirectory() as tmp: + site = Path(tmp) + (site / "guide").mkdir() + (site / "guide" / "_sidebar.yaml").write_text( + "website:\n" + " sidebar:\n" + " - id: guides\n" + " contents:\n" + " - file: guide/workflows/introduction-to-workflows.qmd\n" + " contents:\n" + " - guide/workflows/workflow-states.qmd\n" + " # - guide/workflows/workflow-configuration-examples.qmd\n" + " - text: \"Conditional requirements\"\n" + " file: guide/workflows/conditional-step-requirements.qmd\n" + " - guide/workflows/workflow-states.qmd\n", + encoding="utf-8", + ) + order = gen.load_sidebar_order(site) + self.assertEqual( + list(order), + [ + "/guide/workflows/introduction-to-workflows.html", + "/guide/workflows/workflow-states.html", + "/guide/workflows/conditional-step-requirements.html", + ], + ) + + def test_sidebar_order_breaks_ties_within_a_section(self) -> None: + route = gen.ProductRoute(path="/workflows", label="Workflows") + listed = [ + "/guide/workflows/introduction-to-workflows.html", + "/guide/workflows/manage-record-stages.html", + ] + unlisted = "/guide/workflows/approve-workflow-steps.html" + sidebar_order = {path: i for i, path in enumerate(listed)} + related = [ + r.path + for r in gen.rank_related_docs(route, sorted(listed + [unlisted]), sidebar_order) + ] + # Sidebar position wins over path order, and pages missing from the + # sidebar sort after every listed page in the same tier. + self.assertEqual(related, listed + [unlisted]) + + def test_workflow_routes_keep_manage_record_stages(self) -> None: + """Regression for sc-18087: the cap must not evict manage-record-stages.""" + site = Path(__file__).resolve().parents[1] + snapshot = site / "llm" / gen.DEFAULT_SNAPSHOT_NAME + routes = gen.merge_routes(*gen.load_frontend_snapshot(snapshot)) + all_paths = gen.collect_all_doc_qmd_paths(site) + sidebar_order = gen.load_sidebar_order(site) + for path in ("/settings/workflows", "/settings/workflow-states", "/workflows"): + with self.subTest(route=path): + related = [ + r.path + for r in gen.suggest_related_docs(routes[path], all_paths, sidebar_order) + ] + self.assertIn( + "/guide/workflows/manage-record-stages.html", + related, + msg=( + "manage-record-stages no longer fits in this route's " + f"{gen.RELATED_DOCS_CAP} related-doc slots. Related docs follow the " + "order of site/guide/_sidebar.yaml, so a page added ahead of it in the " + "Workflows section pushes it out. See " + "site/llm/chatbot-product-map-dropped.md and check with the docs team." + ), + ) + self.assertNotIn( + "/guide/risk-tiering/set-up-risk-tiering-workflows.html", related + ) + + def test_risk_tier_templates_route_keeps_risk_tiering_guide(self) -> None: + """Regression for sc-18087: section ranking must not evict the route's own guide.""" + site = Path(__file__).resolve().parents[1] + snapshot = site / "llm" / gen.DEFAULT_SNAPSHOT_NAME + routes = gen.merge_routes(*gen.load_frontend_snapshot(snapshot)) + all_paths = gen.collect_all_doc_qmd_paths(site) + sidebar_order = gen.load_sidebar_order(site) + related = [ + r.path + for r in gen.suggest_related_docs( + routes["/settings/risk-tier-templates"], all_paths, sidebar_order + ) + ] + self.assertIn("/guide/risk-tiering/manage-risk-tier-templates.html", related) + risk_tiering = [p for p in related if p.startswith("/guide/risk-tiering/")] + self.assertEqual(related[: len(risk_tiering)], risk_tiering) + + def test_integrations_routes_list_their_own_guides(self) -> None: + """Regression for sc-18087: integrations screens list integrations guides.""" + site = Path(__file__).resolve().parents[1] + snapshot = site / "llm" / gen.DEFAULT_SNAPSHOT_NAME + routes = gen.merge_routes(*gen.load_frontend_snapshot(snapshot)) + all_paths = gen.collect_all_doc_qmd_paths(site) + sidebar_order = gen.load_sidebar_order(site) + own_guides = { + "/settings/integrations/connections": "/guide/integrations/configure-connections.html", + "/settings/integrations/secrets": "/guide/integrations/manage-secrets.html", + "/settings/integrations/data-exports": "/guide/integrations/configure-data-exports.html", + } + for route_path, guide in own_guides.items(): + with self.subTest(route=route_path): + related = [ + r.path + for r in gen.suggest_related_docs(routes[route_path], all_paths, sidebar_order) + ] + self.assertIn(guide, related) + self.assertTrue( + all(p.startswith("/guide/integrations/") for p in related), related + ) + def test_parse_settings_index_resolves_copy_titles(self) -> None: import tempfile