diff --git a/.cursor/skills/create-user-documentation/SKILL.md b/.cursor/skills/create-user-documentation/SKILL.md new file mode 100644 index 0000000000..249cf53102 --- /dev/null +++ b/.cursor/skills/create-user-documentation/SKILL.md @@ -0,0 +1,417 @@ +--- +name: create-user-documentation +description: Generate or update user documentation for ValidMind software features. Use when creating .qmd files, updating docs based on Shortcut stories/epics, or following ValidMind style conventions. +--- + +# Create User Documentation + +Use this skill when creating new or updating existing user documentation for ValidMind software features. + +--- + +## Workflow + +### 1. Gather Context from Typical Inputs + +Documentation updates typically start with these inputs from the writer: + +#### Shortcut Context (Primary Source) +The writer provides Shortcut story/epic IDs or links. Use these to gather: +- `stories-get-by-id` — Full story details, acceptance criteria, description +- `epics-get-by-id` — Epic overview for larger features +- `stories-search` — Find related stories in the same epic or with similar labels + +**Always check for parent epic:** When given a story ID, check if it belongs to an epic (`epic_id` field in the story). If so, fetch the epic with `epics-get-by-id` — epics often contain: +- Broader feature context and goals +- Links to backend/frontend GitHub PRs +- Related stories that may affect documentation +- Overall acceptance criteria beyond the individual story + +**Extract from Shortcut:** +- Feature requirements and acceptance criteria +- User-facing behavior descriptions +- Edge cases and limitations +- Related stories for cross-references +- GitHub PR links (often found in epic or story descriptions/comments) + +#### Backend/Frontend PRs (Implementation Details) +The writer provides PR numbers or links. Use these to understand what changed: +- `get_pull_request` — PR description, context, reviewer comments +- `get_pull_request_files` — List of changed files +- `get_file_contents` — Read specific implementation files if needed + +**Extract from PRs:** +- Actual UI changes and new fields/buttons +- API changes or new endpoints +- Configuration options +- Implementation notes from PR description + +#### Screenshots from Demos +The writer attaches screenshots showing the feature in action. Use these to: +- Verify UI element names and locations +- Understand the user flow +- Identify what needs visual documentation +- Confirm the feature matches Shortcut acceptance criteria + +#### Writer's Notes +The writer provides human context such as: +- Draft content or bullet points +- Specific sections to focus on +- Questions to address +- Audience considerations +- Links to existing docs that need updating + +#### Notion (Optional — Feature Specs) +If available, the writer may provide Notion links to feature specs: +- `notion-fetch` — Retrieve full page content +- Look for: detailed requirements, UI mockups, stakeholder context + +### 2. Choose the Appropriate Template + +Templates are available in `internal/templates/`. Choose based on content type: + +#### Task Template (`internal/templates/task.qmd`) +Step-by-step instructions for completing a specific action. +- Use for: "How to configure X", "Setting up Y", "Managing Z" +- Structure: Prerequisites → Steps → Troubleshooting → What's next +- **Title convention:** Start with a verb, nouns in plural (e.g., "Register models in the inventory") + +#### Concept Template (`internal/templates/concept.qmd`) +Understanding a feature or system. +- Use for: "What is X?", "How X works", "Understanding Y" +- Structure: Introduction → Key concepts → Examples → What's next +- **Title convention:** Nouns only, end with `-overview` if introducing a product area + +#### Reference Template (`internal/templates/reference.qmd`) +Technical specifications or API details. +- Use for: Field descriptions, configuration options, API endpoints +- Structure: Sections → Subsections → Additional Resources +- **Note:** Only use if content cannot be generated programmatically + +#### Other Templates +- `mermaid-diagrams.qmd` — For process flows and diagrams +- `tachyons-flexbox.qmd` — For responsive column layouts +- `single-source/` — For content shared between guides and training + +--- + +## Style Guide Reference + +Follow the ValidMind style guide at `site/about/contributing/style-guide/` in the documentation repo. Key principles summarized below — refer to the full guide for details. + +### Voice and Tone + +**Human-first approach:** +- Use **active voice** — "You'll need to review" not "The content will be reviewed by you" +- Use **common language** — Define acronyms on first use +- **Break it down** — Bulleted lists, visual aids, digestible parts + +**Inclusive and welcoming:** +- Show empathy, acknowledge user frustrations +- Focus on solutions, not problems +- Use bias-free communication +- Provide alt text for images + +**Conversational but professional:** +- Address reader directly (second person: "you") +- Use contractions where appropriate +- Avoid stiff formality + +### Conventions + +**American English** spelling and grammar. + +**Titles:** +- Task titles: Start with verb, nouns in plural ("Register models in the inventory") +- Parent tasks: Use gerund ("Working with the model inventory") +- Reference titles: Name only, or end with "reference" + +**Formatting:** + +| Element | Format | Example | +|---------|--------|---------| +| UI elements (interactive) | Bold | **{{< fa cubes >}} Inventory** | +| Statuses/roles | Bubble class | `[Status Name]{.bubble}` | +| First use of terms | Italics | *Uncertainty* is defined as... | +| Code/params/files | Backticks | `.env` file, `classifier_full_suite` | +| Smallcaps UI | Smallcaps class | `[model status]{.smallcaps}` | + +**UI element bolding:** +- Bold UI elements only when the user must interact with them directly in a numbered step (e.g., "Click **Settings**"). +- Do not bold UI elements when mentioned descriptively (e.g., "tasks appear under the Tasks tab"). + +**List punctuation:** +- End list items with a period if the item contains a verb. +- List items that are noun phrases only (no verb) do not need a period. + +**Callouts:** +```markdown +::: {.callout title="Note or tip"} +Supplemental information. +::: + +::: {.callout-important title="Warning"} +Critical information or caveats. +::: +``` + +**Links:** +- Always use `.qmd` extension, not `.html` +- Use absolute paths from site root: `/guide/feature/page.qmd` +- Use margin footnotes instead of inline links in instructional text +- Use variables for product names: `{{< var validmind.platform >}}` + +**Footnotes (at end of file):** +```markdown + + +[^1]: [Register models in the inventory](/guide/model-inventory/register-models-in-inventory.qmd) + +[^2]: [Manage permissions](/guide/configuration/manage-permissions.qmd) +``` + +**Screenshots:** +```markdown +![Description](image.png){fig-alt="Detailed alt text" .screenshot} +``` + +**Responsive columns (use Tachyons, NOT CSS Grid):** +```markdown +:::: {.flex .flex-wrap .justify-around} + +::: {.w-50-ns} +Column 1 +::: + +::: {.w-50-ns} +Column 2 +::: + +:::: +``` + +--- + +## Required File Structure + +### YAML Header (Required) +```yaml +--- +# Copyright © 2023-2026 ValidMind Inc. All rights reserved. +# Refer to the LICENSE file in the root of this repository for details. +# SPDX-License-Identifier: AGPL-3.0 AND ValidMind Commercial +title: "Title in Sentence Case" +date: last-modified +--- +``` + +### Opening Paragraph +- One sentence describing what the page covers and why it matters +- No heading before this paragraph + +### Prerequisites Block (for tasks) +```markdown +::: {.attn} + +## Prerequisites + +- [x] {{< var link.login >}} +- [x] Additional prerequisite +- [x] Required role or permission[^1] + +::: +``` + +--- + +## Navigation Updates + +When creating new pages, update the appropriate navigation file: + +- **Sidebar navigation:** `site/guide/_sidebar.yaml`, `site/get-started/_sidebar.yaml`, etc. +- **Main config:** `site/_quarto.yml` for top-level pages +- **Listing pages:** Parent `.qmd` files with `listing:` YAML for grid layouts + +**Always add aliases when moving/renaming files:** +```yaml +aliases: + - /old/path/to/page.html +``` + +--- + +## Review Checklist + +Before finalizing: +- [ ] Copyright header present +- [ ] Title follows sentence case and naming conventions +- [ ] Prerequisites listed (for tasks) +- [ ] Steps are numbered and actionable +- [ ] UI elements are bolded with Font Awesome icons +- [ ] Links use `.qmd` extension and absolute paths +- [ ] Images have descriptive alt text and `.screenshot` class +- [ ] Footnotes for cross-references (not inline links) +- [ ] American English spelling +- [ ] Active voice throughout +- [ ] Page added to navigation (`_sidebar.yaml` or `_quarto.yml`) + +--- + +## Example Prompts + +**Creating new documentation:** +> "Create documentation for the new attestation feature. Here's the Notion spec: [URL]. The Shortcut epic is #1234." + +**Updating existing documentation:** +> "Update the model registration docs to include the new bulk import feature from PR #567." + +**From scratch with context:** +> "I need to document how users configure webhook notifications. I'll provide screenshots and the Shortcut story has acceptance criteria." + +--- + +## Training Materials (Revealjs) + +Training courses use a different format and style. Templates are in `site/training/training-templates/`. + +### Course Structure + +Each course lives in its own subdirectory: `/training/course-name/` + +A course consists of: +1. **Course registration page** (`course-registration.qmd`) — Overview and sign-up +2. **Course slides** (`course-slides.qmd`) — Revealjs presentation + +### Course Registration Template (`training-templates/course-registration.qmd`) + +```yaml +--- +title: "Course Title" +subtitle: For {{< var vm.product >}} +listing: + - id: modules + type: grid + contents: + # IMPORTANT: Use .html path for revealjs output + - path: course-slides.html + title: "Module Title" + subtitle: "Module 1" + description: "{{< fa check >}} Learning point 1
{{< fa check >}} Learning point 2" + reading-time: "30" +--- +``` + +### Course Slides Template (`training-templates/course-slides.qmd`) + +**YAML Header:** +```yaml +--- +title: "Module Title" +subtitle: "Course Name — Module # of #" +lightbox: true +format: + revealjs: + include-in-header: + - text: | + + theme: [default, ../assets/slides.scss] + slide-number: true + footer: "{{< var validmind.training >}} | [Home {{< fa person-walking-dashed-line-arrow-right >}}](/training/training.qmd)" + revealjs-plugins: + - slideover + html: + output-file: _course-slides.html + search: false +title-slide-attributes: + data-background-color: "#083E44" + data-background-image: "../assets/home-hero.svg" +--- +``` + +### Training-Specific Conventions + +**Links:** Use inline links (not footnotes) — footnotes don't display in presentation mode. + +**Section Headers:** Use background colors/images for major sections: +```markdown +# Section Title {background-color="#083E44" background-image="/assets/img/about-us-esphere.svg"} +``` + +**Interactive iFrame Embeds:** +```markdown +## {background-iframe="https://app.prod.validmind.ai/" data-preload="yes"} + +:::: {.slideover--r} +Right-aligned modal content over the live platform. +:::: +``` + +**Slideover Positions:** +- `.slideover--r` — Right-aligned +- `.slideover--l` — Left-aligned +- `.slideover--t` — Top-aligned +- `.slideover--b` — Bottom-aligned + +**Slideover Options:** +- `.auto-collapse` — Auto-collapse after 5 seconds +- `.auto-collapse-10` — Auto-collapse after 10 seconds +- `.three-quarters`, `.half`, `.third` — Width options + +**Scrollable Content:** +```markdown +## {.scrollable} + +:::: {.columns} +::: {.column width="30%"} +Summary content +::: + +::: {.column width="70%" .bl .pl4} +Detailed instructions (scrollable) +::: +:::: +``` + +**Embed Callout (within slideovers):** +```markdown +::: {.embed} +Important information styled as a nested callout. +::: +``` + +**Learning Objectives Format:** +```markdown +# Learning objectives {.center} + +_"As a {{ role }} who ... {{< var vm.product >}}, I want to learn how to {{ task A }}, {{ task B }}, and {{ task C }}."_ +``` + +**Summary Slide Format:** +```markdown +In this module, you learned how to: + +- [x] Task 1 +- [x] Task 2 +- [x] Task 3 +``` + +--- + +## MCP Tool Reference + +### Notion +- `notion-search` — Find pages/databases by keyword +- `notion-fetch` — Get full page content by URL or ID + +### Shortcut +- `stories-search` — Find stories by various filters +- `stories-get-by-id` — Get full story details +- `epics-get-by-id` — Get epic details +- `iterations-get-active` — Current sprint context + +### GitHub +- `list_pull_requests` — Find PRs by state/branch +- `get_pull_request` — Full PR details +- `get_pull_request_files` — Changed files in PR +- `list_commits` — Recent commits +- `get_file_contents` — Read specific files diff --git a/site/guide/_sidebar.yaml b/site/guide/_sidebar.yaml index 4db6ecc9f2..8fe3da897d 100644 --- a/site/guide/_sidebar.yaml +++ b/site/guide/_sidebar.yaml @@ -42,7 +42,8 @@ website: contents: - guide/integrations/manage-secrets.qmd - guide/integrations/configure-connections.qmd - - guide/integrations/linking-external-models.qmd + - guide/integrations/implement-custom-integrations.qmd + - guide/integrations/link-external-models.qmd - guide/integrations/integrations-examples.qmd - text: "---" - text: "Workflows" diff --git a/site/guide/integrations/configure-connections.qmd b/site/guide/integrations/configure-connections.qmd index 1e42ae5420..587b3b88b1 100644 --- a/site/guide/integrations/configure-connections.qmd +++ b/site/guide/integrations/configure-connections.qmd @@ -122,6 +122,23 @@ Required configuration details: **[personal access token]{.smallcaps}** : A PAT secret that includes the `api` or `read_api` scope. +### Custom + +A user-defined connection to a third-party system that implements the {{< var vm.product >}} reference API.[^4] + +Use custom integrations to connect internal model registries, proprietary platforms, or any service that exposes data through a compatible API. + +Required configuration details: + +**[endpoint url]{.smallcaps}** +: The base URL of your deployed integration that implements the reference API. + +**[api key]{.smallcaps}** +: A secret containing the API key for authenticating with your integration. + +**[integration types]{.smallcaps}** +: Select which types of objects this integration provides — Model Registry and/or Artifact / Ticket Source. + :::: ## Add connections @@ -207,3 +224,5 @@ If the test is successful, the message **{{< fa check-circle >}} Connection succ [^3]: [Supported connections](#supported-connections) +[^4]: [Implement custom integrations](implement-custom-integrations.qmd) + diff --git a/site/guide/integrations/implement-custom-integrations.qmd b/site/guide/integrations/implement-custom-integrations.qmd new file mode 100644 index 0000000000..8c5f295b0e --- /dev/null +++ b/site/guide/integrations/implement-custom-integrations.qmd @@ -0,0 +1,225 @@ +--- +# Copyright © 2023-2026 ValidMind Inc. All rights reserved. +# Refer to the LICENSE file in the root of this repository for details. +# SPDX-License-Identifier: AGPL-3.0 AND ValidMind Commercial +title: "Implement custom integrations" +date: last-modified +--- + +Connect {{< var vm.product >}} to third-party systems that aren't supported out of the box by building custom integrations using our reference API. + +Custom integrations let you link resources, such as AI systems or models, from internal registries, proprietary platforms, or any service you control to the {{< var vm.product >}} model inventory. + +::: {.attn} + +## Prerequisites + +- [x] {{< var link.login >}} +- [x] You can manage permissions.[^1] +- [x] Your integration service is deployed and accessible from {{< var vm.product >}}. +- [x] You have the endpoint URL and API key for your integration service. +- [x] A secret containing your API key exists in integration secrets.[^2] + +::: + +## How custom integrations work + +To create a custom integration, you build a service that implements the reference API endpoints: + +1. Build a service that implements the required endpoints and connects to your data sources. +2. Deploy your service at a URL accessible to {{< var vm.product >}}. +3. Configure a custom integration in {{< var vm.product >}} that points to your service URL. +4. After implementation, your users can browse and link resources from your system to records in the model inventory. + +Data flows bidirectionally — {{< var vm.product >}} reads your data and can write back metadata to enable linking. + +```{mermaid} +flowchart LR + VM[ValidMind Platform] + API[Your API service] + DATA[Your data sources] + + VM <-->|Reference API| API + API <--> DATA +``` + +## Reference API + +The reference API defines the HTTP endpoints your service must implement. {{< var vm.product >}} calls these endpoints to discover and synchronize resources. + +::: {.callout title="Reference implementation"} +A reference implementation with sample code is available. Contact your ValidMind representative for access. +::: + +### Required endpoints + +Your service must expose these endpoints at the `/api/v1` base path: + +**List models** +: `GET /models` — Returns all models from your system. Supports optional `?resource_type=` filter. + +**Get model** +: `GET /models/{id}` — Returns a specific model by its unique identifier. + +**Update model** (optional) +: `PUT /models/{id}` — Accepts metadata updates from {{< var vm.product >}}, enabling bidirectional sync. + +**Health check** +: `GET /health` — Returns the connection status so users can test the integration. + +### Optional endpoints + +**List tickets** +: `GET /tickets` — Returns tickets or findings from your system. + +**Get ticket** +: `GET /tickets/{id}` — Returns a specific ticket by ID. + +**Schema** +: `GET /schema` — Returns field definitions to enable formula and workflow access to your integration data. + +**Resource types** +: `GET /resource-types` — Returns available resource categories for filtering in the UI. + +### Model response format + +Your models endpoint should return objects with these fields: + +| Field | Required | Description | +|-------|----------|-------------| +| `id` | Yes | Unique identifier | +| `name` | Yes | Human-readable name | +| `status` | No | Lifecycle status (active, training, deprecated) | +| `resource_type` | No | Category for filtering (ml_model, llm, agent) | +| `metadata` | No | Flexible object with additional fields | +| `created_at` | No | ISO 8601 timestamp | +| `updated_at` | No | ISO 8601 timestamp | + +### Authentication + +{{< var vm.product >}} authenticates requests using the `X-API-Key` header. Your service should validate this key and return `401 Unauthorized` if invalid or missing. + +### Bidirectional sync + +When linking resources, {{< var vm.product >}} can write metadata back to your system via `PUT` requests. This bidirectional sync enables you to store the {{< var vm.product >}} model identifier (`vm_cuid`) alongside your external records, creating a two-way link between systems. + +::: {.callout collapse="true" title="Code examples"} + +**GET /models response** + +```json +[ + { + "id": "model-001", + "name": "fraud-detection-xgboost", + "status": "active", + "resource_type": "ml_model", + "metadata": { + "framework": "xgboost", + "version": "2.1.3" + }, + "created_at": "2024-01-15T10:30:00Z", + "updated_at": "2024-01-22T14:20:00Z" + } +] +``` + +**PUT /models/{id} request body** (what {{< var vm.product >}} sends) + +```json +{ + "vm_cuid": "mdl_abc123xyz" +} +``` + +**Health check response** + +```json +{ + "status": "healthy" +} +``` + +**Error response format** + +```json +{ + "detail": "Model not found" +} +``` + +::: + +## Set up custom integrations + +### Best practices + +**Secure your service** +: Deploy your integration service behind HTTPS. Validate the API key on every request. + +**Handle errors gracefully** +: Return appropriate HTTP status codes (`400`, `401`, `404`, `500`) and error messages so users can troubleshoot connection issues. + +**Paginate large responses** +: If your external system contains many resources, implement pagination to keep responses fast. + +**Monitor availability** +: Track the health of your integration service. {{< var vm.product >}} displays connection status in the UI, so users notice outages quickly. + +**Version your API** +: Include version information in your API path (`/api/v1/`) to support future changes without breaking existing integrations. + +### Add a custom integration + +1. In the left sidebar, click **{{< fa gear >}} Settings**. + +2. Under Integrations, select **Connections**. + +3. Click **{{< fa plus >}} Add Connection**. + +4. In the modal that opens, select **Custom Integration**. + +5. Enter the: + + - **[integration name]{.smallcaps}** — A display name to identify this integration. + - **[description]{.smallcaps}** (optional) — Additional details about the intended usage. + - **[endpoint url]{.smallcaps}** — The base URL of your deployed integration that implements the reference API. + - **[api key]{.smallcaps}** — Select a secret containing the API key for authenticating with your integration. + - **[integration types]{.smallcaps}** — Select which types of objects this integration provides: + - **Model Registry** — Sync models from your external system. + - **Artifact / Ticket Source** — Sync artifacts or tickets from your external system. + - **[initial status]{.smallcaps}** — Set to `Operational` to enable immediately or `Disabled` to finish setup later. + +6. Click **Save Integration**. + +7. Test the connection to verify your service is reachable: + + a. Hover over the custom integration you created. + + b. When the **{{< fa ellipsis-vertical >}}** menu appears, click it and select **{{< fa circle-check >}} Test Connection**. + + If the test succeeds, the message **{{< fa check-circle >}} Connection successful** displays. + +### Link resources + +After configuring your custom integration, link resources to models in the inventory: + +1. In the left sidebar, click **{{< fa cubes >}} Inventory**. + +2. Select a model by clicking on it. + +3. In the right sidebar, locate your custom integration connection. + +4. Hover over the connection. + +5. When the **{{< fa ellipsis-vertical >}}** menu appears, click it and select **{{< fa link >}} Link Model**. + +6. In the modal that opens, select the resource from your external system. + +7. Click **Link Model**. + + + +[^1]: [Manage permissions](/guide/configuration/manage-permissions.qmd) + +[^2]: [Manage secrets](manage-secrets.qmd) diff --git a/site/guide/integrations/linking-external-models.qmd b/site/guide/integrations/link-external-models.qmd similarity index 98% rename from site/guide/integrations/linking-external-models.qmd rename to site/guide/integrations/link-external-models.qmd index 33d25665e7..70318c1d94 100644 --- a/site/guide/integrations/linking-external-models.qmd +++ b/site/guide/integrations/link-external-models.qmd @@ -4,6 +4,8 @@ # SPDX-License-Identifier: AGPL-3.0 AND ValidMind Commercial title: "Linking external models" date: last-modified +aliases: + - /guide/integrations/linking-external-models.html --- Link models in the {{< var vm.product >}} model inventory to external systems to keep model information synchronized. @@ -112,4 +114,3 @@ The model is unlinked from the external system. [^6]: [Configure connections](configure-connections.qmd) [^7]: [Working with the model inventory](/guide/model-inventory/working-with-model-inventory.qmd#search-filter-and-sort-models) - diff --git a/site/guide/integrations/managing-integrations.qmd b/site/guide/integrations/managing-integrations.qmd index a294aaf201..adba0ee80d 100644 --- a/site/guide/integrations/managing-integrations.qmd +++ b/site/guide/integrations/managing-integrations.qmd @@ -14,7 +14,8 @@ listing: contents: - manage-secrets.qmd - configure-connections.qmd - - linking-external-models.qmd + - implement-custom-integrations.qmd + - link-external-models.qmd - integrations-examples.qmd --- @@ -90,6 +91,10 @@ Link to models in external registries and development platforms and keep invento - GitLab ::: +::: {.w-20-ns} +- Custom integrations +::: + :::: ---