@checkstack/ai-backend 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @checkstack/ai-backend
2
2
 
3
+ ## 0.1.6
4
+
5
+ ### Patch Changes
6
+
7
+ - f9cfdae: fix(dependency): gate the dependency map behind its own non-public access rule
8
+
9
+ Anonymous users could see the "Dependency Map" nav entry and open the page
10
+ (which then rendered empty) because the map was gated by `dependency.read`,
11
+ which is public so that dependency _warning_ badges stay visible on the
12
+ catalog and dashboard.
13
+
14
+ The full topology map is now gated by a dedicated `dependency.map` access
15
+ rule that is granted to authenticated users by default but is NOT public, so
16
+ anonymous visitors no longer see the nav entry or reach the page. The
17
+ `getAllDependencies`, `getNodePositions`, and `saveNodePositions` endpoints
18
+ move to this rule too, and the dashboard dependency signal now renders as
19
+ plain text (not a map link) for users without map access. Per-system
20
+ dependency warnings stay on the public `dependency.read` rule, so warning
21
+ badges/alerts/signals remain visible to everyone as before.
22
+
23
+ Admins can still grant `dependency.map` to the anonymous role to make the
24
+ map public again.
25
+
26
+ Note: the default-rule sync is add-only, so on existing deployments the
27
+ anonymous role keeps any rules already granted. Since `dependency.map` is a
28
+ brand-new rule the anonymous role never had it, so the map is hidden from
29
+ anonymous users immediately after upgrade with no admin action required.
30
+
31
+ - @checkstack/sdk@0.101.1
32
+
3
33
  ## 0.1.5
4
34
 
5
35
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@checkstack/ai-backend",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "license": "Elastic-2.0",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -21,7 +21,7 @@
21
21
  "@checkstack/common": "0.15.0",
22
22
  "@checkstack/drizzle-helper": "0.0.5",
23
23
  "@checkstack/integration-backend": "0.4.5",
24
- "@checkstack/sdk": "0.100.1",
24
+ "@checkstack/sdk": "0.101.1",
25
25
  "@orpc/client": "^1.14.4",
26
26
  "@orpc/contract": "^1.14.4",
27
27
  "@orpc/server": "^1.14.4",
@@ -2244,7 +2244,7 @@ export const DOCS_INDEX: readonly DocsIndexEntry[] = [
2244
2244
  "Where this maps in the data model",
2245
2245
  "Where to go next"
2246
2246
  ],
2247
- "content": "The catalog is the backbone of Checkstack. Everything else (health checks, incidents, maintenances, notifications) attaches to a System. This page explains what a System is, how Groups organise them, and how Dependencies model real-world impact between Systems.\n\n## Systems\n\nA **System** is the smallest unit you monitor. It usually maps to one logical service in your stack: a database, an API, a worker, a third-party endpoint, a Minecraft server, a Jenkins controller, anything you want to know the health of.\n\nEvery system carries:\n\n- A **name** (required) and an optional **description**.\n- **Contacts**, which are either platform users or free-form mailboxes (email addresses). Contacts surface on the system detail page so anyone responding to an incident knows who owns it.\n- **Links**, which are free-form URL hotlinks (runbooks, Jira boards, dashboards) shown alongside the system.\n- Membership in zero or more **Groups**.\n\n> [!TIP]\n> Be ruthless about what counts as a System. One System per service is the right granularity. If you find yourself making a \"Foo - production\" and \"Foo - staging\" pair, that is fine; if you start making \"Foo - login flow\" and \"Foo - checkout flow\", you have probably blurred the line between a System and a health check.\n\n### What a System is not\n\nA System is not the same as a host, an environment, or a Kubernetes pod. It is the *logical* thing you care about. The health check is what decides \"this URL on this host is the way I observe it\".\n\n## Groups\n\nA **Group** is a flat label that bundles related systems together. Use groups to model:\n\n- **Teams.** \"Payments\", \"Identity\", \"Platform\".\n- **Tiers.** \"Tier 1\", \"Customer-facing\", \"Internal-only\".\n- **Domains.** \"Production\", \"Staging\" (though you can also model environments as separate systems).\n\nGroups are flat. Checkstack does not nest groups inside other groups today. A system can belong to multiple groups, so you can cross-cut by team and by tier at the same time.\n\n> [!NOTE]\n> Subscribing to notifications for a group automatically catches every system in that group. When the catalog adds or removes a system from the group, group subscribers update instantly without you re-subscribing per system.\n\nGroups are managed under **Catalog -> Groups** in the UI. You can drag systems between groups, rename groups in place, and delete them when they become empty. The management page carries the same toolbar as the browse view, so you can search and filter the systems and groups lists while you arrange them.\n\n> [!TIP]\n> Drag-and-drop assignment is keyboard-operable. Focus a system's drag handle, press Space or Enter to pick it up, move between groups with the arrow keys, and press Space or Enter again to drop it (Escape cancels). The assign button on each system row is an equivalent pointer-free alternative.\n\n## Dependencies\n\nA **Dependency** is a directional edge between two systems: \"Payment API depends on Payment DB\". When the upstream system is unhealthy, the downstream system's effective state reflects that impact.\n\nEach dependency carries an **impact type**:\n\n- **`informational`** records the link in the dependency map but does not change downstream state.\n- **`degraded`** marks the downstream system as degraded if the upstream is unhealthy.\n- **`critical`** marks the downstream system as unhealthy if the upstream is unhealthy.\n\n```\n depends on\nPayment API ----------> Payment DB\n (downstream) (upstream)\n impactType: critical\n```\n\nYou can attach optional **per-health-check rules** to a dependency. By default the impact applies whenever the upstream system is unhealthy on any of its checks; with rules you can scope the impact to specific checks only. For example, \"Payment API only goes degraded when Payment DB's TLS check fails, not when its replication-lag check fails.\"\n\nA dependency can also be marked **transitive** to let it cascade further down the chain.\n\n> [!IMPORTANT]\n> Dependencies do not auto-open incidents. They affect derived health state and which alerts get suppressed in cascades, nothing more. See [Incidents](/checkstack/user-guide/concepts/incidents/) for the human workflow.\n\nThe dependency map lives under **Catalog -> Dependencies**. Node positions are saved per user, so your layout follows you across devices.\n\n## Putting it together\n\nA small example of how the pieces compose for an e-commerce stack:\n\n```\nGroups:\n - \"Payments team\": [Payment API, Payment DB, Stripe webhook]\n - \"Tier 1\": [Payment API, Checkout API, Storefront]\n\nSystems:\n Storefront ----(critical)---> Checkout API\n Checkout API ----(critical)---> Payment API\n Payment API ----(critical)---> Payment DB\n ----(degraded)---> Stripe webhook\n```\n\nA failing Payment DB now drives the derived state for Payment API, Checkout API, and Storefront. A failing Stripe webhook only degrades Payment API. Anyone subscribed to the \"Payments team\" group sees the relevant notifications; anyone subscribed to \"Tier 1\" sees the customer-facing ones.\n\n## Browsing the catalog\n\nThe catalog home page is a read-only, group-first browse view. It is the landing page for everyone with catalog read access, managers and non-managers alike. It is built to stay legible at hundreds of systems across many groups.\n\nThe view organises systems into collapsible **group sections**. Each section header shows the group name and its member count. A synthetic **Ungrouped** section collects systems that belong to no group. Because a system can belong to several groups, it appears under each group it is a member of.\n\n### Inline health rollups\n\nWhen a health source such as the healthcheck plugin is installed, each group header also shows a **health rollup** pill summarising its members at a glance: \"All healthy\", \"N degraded\", or \"N unhealthy\" (the worst member status wins, with a count). Individual unhealthy or degraded systems still show their own badge on the row; healthy systems show none, so the absence of a badge means healthy or not yet measured.\n\nThe rollup drives the default open state: groups where every member is healthy start **collapsed** so your attention goes to the groups that need it, while any group with a degraded, unhealthy, or not-yet-measured member starts **expanded**. You can always toggle a section open or closed yourself, and that choice is captured in the URL. With no health source installed, headers show member counts only and every group starts expanded.\n\nThe **Health** filter then lets you narrow to a single state. Selecting `unknown` shows systems with no measured health (no checks wired yet); a system with no reported health is never silently counted as healthy.\n\nA toolbar above the sections lets you narrow what you see:\n\n- **Search** matches systems and groups by name and description, case-insensitively. A match inside a collapsed group auto-expands that group; groups with no match drop out while you are searching.\n- **Group**, **Health**, and **Tag** filters narrow the list further. Filters compose: applying more than one shows only the systems that satisfy all of them. (The Health filter activates once a health source such as the healthcheck plugin is installed.)\n- **Density** switches rows between Comfortable (descriptions shown inline) and Compact (single-line rows, descriptions on hover).\n\nEvery part of the view state lives in the URL, so a filtered, searched view is a shareable link. For example:\n\n```text\n/catalog/?q=checkout&group=payments&density=compact\n```\n\nopens the catalog pre-filtered to the Payments group, searching for \"checkout\", in compact density. Open or closed group sections are captured in the link too, so a teammate opening it sees exactly what you see.\n\nManagers see a **Manage catalog** link in the header that jumps to the management page below.\n\n## UI tour\n\n| Where to go | What you do there |\n|-------------|-------------------|\n| **Catalog** (home) | Browse, search, and filter every system, grouped by team or domain. Read-only. |\n| **Catalog -> Systems** | Create, edit, and delete systems. Set contacts and hotlinks. |\n| **Catalog -> Groups** | Create groups, drag systems in and out. |\n| **Catalog -> Dependencies** | Visual graph editor. Click a system to connect it to another. |\n| **System detail page** | See attached health checks, recent runs, contacts, links, and the systems that depend on it. |\n\n## Where this maps in the data model\n\nFor operators who want to peek behind the curtain:\n\n- Systems live in the `catalog-backend` plugin's schema, in the `systems` table.\n- Groups live in the `groups` table; the join is `systems_groups`.\n- Hotlinks and contacts live in `system_links` and `system_contacts`.\n- Dependencies are stored by `dependency-backend` in the `dependencies` table.\n\nYou should rarely need to query these directly, but the structure is open: every read happens through the platform's typed RPC and respects [Teams and access](/checkstack/user-guide/concepts/teams-and-access/).\n\n## Where to go next\n\n- **First system, first check.** Walk through [Set up your first health check](/checkstack/user-guide/guides/first-health-check/).\n- **Notifications.** Read [Notifications](/checkstack/user-guide/concepts/notifications/) to understand how group membership drives delivery.\n- **YAML-as-code.** The [GitOps](/checkstack/user-guide/concepts/gitops/) flow lets you express systems, groups, and dependencies as YAML in a Git repo.",
2247
+ "content": "The catalog is the backbone of Checkstack. Everything else (health checks, incidents, maintenances, notifications) attaches to a System. This page explains what a System is, how Groups organise them, and how Dependencies model real-world impact between Systems.\n\n## Systems\n\nA **System** is the smallest unit you monitor. It usually maps to one logical service in your stack: a database, an API, a worker, a third-party endpoint, a Minecraft server, a Jenkins controller, anything you want to know the health of.\n\nEvery system carries:\n\n- A **name** (required) and an optional **description**.\n- **Contacts**, which are either platform users or free-form mailboxes (email addresses). Contacts surface on the system detail page so anyone responding to an incident knows who owns it.\n- **Links**, which are free-form URL hotlinks (runbooks, Jira boards, dashboards) shown alongside the system.\n- Membership in zero or more **Groups**.\n\n> [!TIP]\n> Be ruthless about what counts as a System. One System per service is the right granularity. If you find yourself making a \"Foo - production\" and \"Foo - staging\" pair, that is fine; if you start making \"Foo - login flow\" and \"Foo - checkout flow\", you have probably blurred the line between a System and a health check.\n\n### What a System is not\n\nA System is not the same as a host, an environment, or a Kubernetes pod. It is the *logical* thing you care about. The health check is what decides \"this URL on this host is the way I observe it\".\n\n## Groups\n\nA **Group** is a flat label that bundles related systems together. Use groups to model:\n\n- **Teams.** \"Payments\", \"Identity\", \"Platform\".\n- **Tiers.** \"Tier 1\", \"Customer-facing\", \"Internal-only\".\n- **Domains.** \"Production\", \"Staging\" (though you can also model environments as separate systems).\n\nGroups are flat. Checkstack does not nest groups inside other groups today. A system can belong to multiple groups, so you can cross-cut by team and by tier at the same time.\n\n> [!NOTE]\n> Subscribing to notifications for a group automatically catches every system in that group. When the catalog adds or removes a system from the group, group subscribers update instantly without you re-subscribing per system.\n\nGroups are managed under **Catalog -> Groups** in the UI. You can drag systems between groups, rename groups in place, and delete them when they become empty. The management page carries the same toolbar as the browse view, so you can search and filter the systems and groups lists while you arrange them.\n\n> [!TIP]\n> Drag-and-drop assignment is keyboard-operable. Focus a system's drag handle, press Space or Enter to pick it up, move between groups with the arrow keys, and press Space or Enter again to drop it (Escape cancels). The assign button on each system row is an equivalent pointer-free alternative.\n\n## Dependencies\n\nA **Dependency** is a directional edge between two systems: \"Payment API depends on Payment DB\". When the upstream system is unhealthy, the downstream system's effective state reflects that impact.\n\nEach dependency carries an **impact type**:\n\n- **`informational`** records the link in the dependency map but does not change downstream state.\n- **`degraded`** marks the downstream system as degraded if the upstream is unhealthy.\n- **`critical`** marks the downstream system as unhealthy if the upstream is unhealthy.\n\n```\n depends on\nPayment API ----------> Payment DB\n (downstream) (upstream)\n impactType: critical\n```\n\nYou can attach optional **per-health-check rules** to a dependency. By default the impact applies whenever the upstream system is unhealthy on any of its checks; with rules you can scope the impact to specific checks only. For example, \"Payment API only goes degraded when Payment DB's TLS check fails, not when its replication-lag check fails.\"\n\nA dependency can also be marked **transitive** to let it cascade further down the chain.\n\n> [!IMPORTANT]\n> Dependencies do not auto-open incidents. They affect derived health state and which alerts get suppressed in cascades, nothing more. See [Incidents](/checkstack/user-guide/concepts/incidents/) for the human workflow.\n\nThe dependency map lives under **Workspace -> Dependency Map**. Node positions are saved per user, so your layout follows you across devices.\n\n> [!NOTE]\n> The full dependency map is gated by its own access rule and is shown to signed-in users by default, not to anonymous visitors. Per-system dependency *warnings* (the badges and dashboard signals) stay public, so anonymous visitors still see when a system is affected by an upstream problem - they just do not get the full topology view. Admins can grant the map to the anonymous role under **Teams & access** to make it public.\n\n## Putting it together\n\nA small example of how the pieces compose for an e-commerce stack:\n\n```\nGroups:\n - \"Payments team\": [Payment API, Payment DB, Stripe webhook]\n - \"Tier 1\": [Payment API, Checkout API, Storefront]\n\nSystems:\n Storefront ----(critical)---> Checkout API\n Checkout API ----(critical)---> Payment API\n Payment API ----(critical)---> Payment DB\n ----(degraded)---> Stripe webhook\n```\n\nA failing Payment DB now drives the derived state for Payment API, Checkout API, and Storefront. A failing Stripe webhook only degrades Payment API. Anyone subscribed to the \"Payments team\" group sees the relevant notifications; anyone subscribed to \"Tier 1\" sees the customer-facing ones.\n\n## Browsing the catalog\n\nThe catalog home page is a read-only, group-first browse view. It is the landing page for everyone with catalog read access, managers and non-managers alike. It is built to stay legible at hundreds of systems across many groups.\n\nThe view organises systems into collapsible **group sections**. Each section header shows the group name and its member count. A synthetic **Ungrouped** section collects systems that belong to no group. Because a system can belong to several groups, it appears under each group it is a member of.\n\n### Inline health rollups\n\nWhen a health source such as the healthcheck plugin is installed, each group header also shows a **health rollup** pill summarising its members at a glance: \"All healthy\", \"N degraded\", or \"N unhealthy\" (the worst member status wins, with a count). Individual unhealthy or degraded systems still show their own badge on the row; healthy systems show none, so the absence of a badge means healthy or not yet measured.\n\nThe rollup drives the default open state: groups where every member is healthy start **collapsed** so your attention goes to the groups that need it, while any group with a degraded, unhealthy, or not-yet-measured member starts **expanded**. You can always toggle a section open or closed yourself, and that choice is captured in the URL. With no health source installed, headers show member counts only and every group starts expanded.\n\nThe **Health** filter then lets you narrow to a single state. Selecting `unknown` shows systems with no measured health (no checks wired yet); a system with no reported health is never silently counted as healthy.\n\nA toolbar above the sections lets you narrow what you see:\n\n- **Search** matches systems and groups by name and description, case-insensitively. A match inside a collapsed group auto-expands that group; groups with no match drop out while you are searching.\n- **Group**, **Health**, and **Tag** filters narrow the list further. Filters compose: applying more than one shows only the systems that satisfy all of them. (The Health filter activates once a health source such as the healthcheck plugin is installed.)\n- **Density** switches rows between Comfortable (descriptions shown inline) and Compact (single-line rows, descriptions on hover).\n\nEvery part of the view state lives in the URL, so a filtered, searched view is a shareable link. For example:\n\n```text\n/catalog/?q=checkout&group=payments&density=compact\n```\n\nopens the catalog pre-filtered to the Payments group, searching for \"checkout\", in compact density. Open or closed group sections are captured in the link too, so a teammate opening it sees exactly what you see.\n\nManagers see a **Manage catalog** link in the header that jumps to the management page below.\n\n## UI tour\n\n| Where to go | What you do there |\n|-------------|-------------------|\n| **Catalog** (home) | Browse, search, and filter every system, grouped by team or domain. Read-only. |\n| **Catalog -> Systems** | Create, edit, and delete systems. Set contacts and hotlinks. |\n| **Catalog -> Groups** | Create groups, drag systems in and out. |\n| **Catalog -> Dependencies** | Visual graph editor. Click a system to connect it to another. |\n| **System detail page** | See attached health checks, recent runs, contacts, links, and the systems that depend on it. |\n\n## Where this maps in the data model\n\nFor operators who want to peek behind the curtain:\n\n- Systems live in the `catalog-backend` plugin's schema, in the `systems` table.\n- Groups live in the `groups` table; the join is `systems_groups`.\n- Hotlinks and contacts live in `system_links` and `system_contacts`.\n- Dependencies are stored by `dependency-backend` in the `dependencies` table.\n\nYou should rarely need to query these directly, but the structure is open: every read happens through the platform's typed RPC and respects [Teams and access](/checkstack/user-guide/concepts/teams-and-access/).\n\n## Where to go next\n\n- **First system, first check.** Walk through [Set up your first health check](/checkstack/user-guide/guides/first-health-check/).\n- **Notifications.** Read [Notifications](/checkstack/user-guide/concepts/notifications/) to understand how group membership drives delivery.\n- **YAML-as-code.** The [GitOps](/checkstack/user-guide/concepts/gitops/) flow lets you express systems, groups, and dependencies as YAML in a Git repo.",
2248
2248
  "truncated": false
2249
2249
  },
2250
2250
  {
@@ -3019,4 +3019,4 @@ export const DOCS_INDEX: readonly DocsIndexEntry[] = [
3019
3019
  ];
3020
3020
 
3021
3021
  /** A content hash of the source tree, so a CI check can detect drift. */
3022
- export const DOCS_INDEX_HASH = "a37429cd2e6f71d57ce52a8084d890e51b47d6c5e662a6ab576e4a05875528d8";
3022
+ export const DOCS_INDEX_HASH = "eb86869a0791795f24c6cad94a2025f66e1314c631a2a320bf5658428d8d157d";