Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 70 additions & 40 deletions docs/docs/immutable-history/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,65 +2,95 @@
title: Immutable history
---

# Understanding immutable history in Infrahub
Infrahub preserves previous values and relationships as your infrastructure data changes. Earlier
versions remain available for queries, so you can inspect what existed at a specific time, compare
changes across a period, and trace how an object or relationship changed.
Comment on lines +5 to +7

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should make sure Claude isn’t adding line breaks where they’re not needed - here for instance it should be a single line


At its foundation, Infrahub implements data immutability—a principle where information in the database cannot be deleted or modified in place. Instead, every change creates a new version while preserving all previous states. This approach mirrors version control systems like Git, providing a robust history of all infrastructure changes.
This is useful for troubleshooting incidents, reviewing the effect of a change, answering audit
questions, and understanding how topology or dependencies evolved. When you specify a timestamp,
Infrahub returns the values and relationships that were valid at that time.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Infrahub returns the schema, object, attributes and relationships that were valid at that time.


This architectural decision provides several critical benefits for infrastructure management:
## What you can do with immutable history

- **Complete audit trail**: Every modification is permanently recorded with who, what, and when, providing full traceability
- **Time travel queries**: Access the exact state of your infrastructure at any point in history to understand past configurations
- **Risk-free rollbacks**: Return to any previous state without data loss when issues are detected
- **Compliance and forensics**: Meet regulatory requirements with immutable change history for audits
- **Parallel workflows**: Enable multiple teams to work on infrastructure changes simultaneously using branches
- **Change verification**: Review proposed changes before committing them to production environments
- Query objects and relationships as they existed at a specific point in time.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

objects, attributes, relationships, schemas

- Compare two timestamps to identify which objects, attributes, or relationships changed.
- Trace a change to the account that made it and the time it happened, through [object
metadata](../objects/metadata.mdx).
- Preserve the history available before a branch was created while recording changes made on that
branch.
- Use previous infrastructure data for troubleshooting, audits, security investigations, and
post-incident analysis.

## Use cases
For example, you can answer questions such as:

Immutable history in Infrahub supports several crucial infrastructure management scenarios:
- Which devices, interfaces, and relationships existed for this site during last night's incident?
- Which interface attributes changed between the last known-good timestamp and now?
- Which services and circuits were related before this topology change?

- **Historical analysis**: View how your infrastructure looked at a specific point in time to troubleshoot issues or understand past decisions
- **Compliance auditing**: Extract all changes performed within a specific time frame for regulatory compliance
- **Change impact assessment**: Compare infrastructure states before and after significant changes
- **Security investigation**: Trace unauthorized or unexpected changes to their source
- **Knowledge preservation**: Understand why specific configuration decisions were made, even as team members change
## Historical data and the Activity log answer different questions

## Core concepts
The Activity log records operations: which objects were affected, when a change occurred, who made

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this would be better:
which object was changed, when that change occurred and who made it; and the sequence of actions.

it, and the sequence of actions.

### Timestamps and commits
Immutable history preserves the versions of data produced by those changes. If you need to know who
changed an interface and when, use the [Activity
log](../deploy-manage/run-observe/activity-log.mdx). If you need to know which interfaces,
addresses, and relationships existed at 14:00 during an incident, query the data for that timestamp.

Every change in Infrahub is organized into commits, each with an immutable timestamp. These commits capture:
When you specify a timestamp, Infrahub returns the values and relationships that were valid then, so
you query that data directly rather than reconstructing it from a backup and the changes recorded
after it.

- The specific data that changed
- Who made the change
- When the change occurred
## How Infrahub preserves history

This approach ensures a complete and coherent historical record that can never be rewritten or deleted.
Each change in Infrahub creates a new version instead of modifying the previous value in place.
Every version is associated with a timestamp, and earlier values remain available for queries that
specify an earlier time.

### Temporal queries
History is tracked at the attribute level. When one field changes, Infrahub records the new value

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me this reads a bit weird.

History is tracked at the object, attribute, relationship and schema level. We can then explain how we track value, related object changes.

It's also a bit weird how we explain the exception about branches.
Maybe to not mention that here as we have a section on it below.

for that field alone. This makes it possible to identify the specific attributes that changed
between two timestamps.

Infrahub's temporal query system allows you to retrieve data from any point in time. When you query the database, you're not just accessing current data—you're accessing a specific moment in the database's history. By default, queries return the latest state, but you can specify any timestamp to see exactly how your infrastructure looked at that moment.
Relationships are versioned as well. A query for a specific timestamp therefore returns both the
attribute values and the object relationships that were valid at that time. This is important for
topology and dependency questions where the connections between objects are part of the answer.

This capability extends across all interfaces:
The schema is versioned the same way. If the schema changed after the timestamp you request,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Custom agent: Flag AI Slop and Fabricated Changes

Historical-query behavior for schema changes is not established, but this paragraph presents timestamped schema loading as guaranteed. The PR description identifies schema temporal support as unresolved, and query setup currently selects a schema by branch rather than demonstrating timestamp resolution. Remove this definitive claim or document the unresolved behavior until implementation is confirmed.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/docs/immutable-history/overview.mdx, line 57:

<comment>Historical-query behavior for schema changes is not established, but this paragraph presents timestamped schema loading as guaranteed. The PR description identifies schema temporal support as unresolved, and query setup currently selects a schema by branch rather than demonstrating timestamp resolution. Remove this definitive claim or document the unresolved behavior until implementation is confirmed.</comment>

<file context>
@@ -2,95 +2,94 @@
-Both are useful for different questions. Use the [activity
-log](../deploy-manage/run-observe/activity-log) to see the sequence of operations someone
-performed; query a past time to see the state those operations produced.
+The schema is versioned the same way. If the schema changed after the timestamp you request,
+Infrahub loads the schema as it was at that point, so the query sees the attributes and
+relationships the schema defined then rather than the ones it defines now.
</file context>

Infrahub loads the schema as it was at that point, so the query sees the attributes and
relationships the schema defined then rather than the ones it defines now.

- **Web UI**: Time navigation controls in the interface
- **GraphQL API**: Timestamp parameters for historical queries
- **REST API**: Temporal query support for retrieving historical data
- **Python SDK**: Time-aware methods to access past states
A graph that stores validity times for both its values and its relationships is a **temporal
graph**. The period during which each value and connection applied is part of the stored data, which
is why you can answer a question about past topology with a query.

### Attribute-level change tracking
Deleting a branch is the exception. Infrahub removes the data and history recorded on that branch,
and that history is not recoverable. Versions on the default branch are unaffected.

Unlike systems that capture entire object snapshots, Infrahub's immutable history operates at the attribute level. This approach offers several advantages:
## How branches use immutable history

- **Storage efficiency**: Only changed values are stored, not entire object copies
- **Change clarity**: Easier identification of exactly what changed in each commit
- **Performance optimization**: Faster queries and better scalability with large datasets
When you create a branch, it starts from the data and history available on the default branch at its

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think here we need to do a better explanation.

The history within a branch is available as long as that branch exists. If we delete the branch then that history will be removed permanently.

When a branch is merged that creates a new object:

  • the creation date of that object in the default branch will be the time of the merge

When a branch is merged that modifies an objectL

  • the modification date in the default branch will become the time of the merge

This means that the history in the default branch will not contain the changes that happened in the merged branch. The history within that branch for a given object within that branch would still be available for as long as that branch exists. Once you delete the branch that historical data will be gone from the branch. However the activity log of that object will still show these changes.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a graphic to explain these concepts would come a long way to explain this better

branch point. Changes made on that branch create new versions there without changing the data on the
default branch.

## Implementation details
You can therefore develop and review multiple changes independently while retaining the history
needed to compare and merge them. See [Branches](../branches/overview.mdx) for the branch creation,
diff, and merge workflow.

There is a timestamp associated with every change in the database. This timestamp is immutable and cannot be changed or deleted. Every query to the database can be associated with a timestamp, allowing you to see the state of the database at that specific point in time.
## Query data at a specific time

## Related topics
By default, queries return the latest data on the selected branch. Set a time when you need the

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe change this to: You can a set a time when you need to the state of the data in Infrahub at an earlier time.

values and relationships that were valid at an earlier timestamp. You can specify a time through the
web interface, GraphQL API, REST API, and Python SDK.

- [Proposed Changes](../proposed-changes/overview.mdx)
- [Branches](../branches/overview.mdx)
See [Query historical data](./query-historical-data.mdx) for the available interfaces, comparing two
timestamps, supported time formats, and branch history limits.

## Related

- [Query historical data](./query-historical-data.mdx) — read the graph at an earlier timestamp,
and compare two timestamps to see what changed
- [Branches](../branches/overview.mdx) — how branches diverge, share history, and merge
- [Proposed Changes](../proposed-changes/overview.mdx) — compare a branch with its base, with
review, validation, and checks
- [Activity log](../deploy-manage/run-observe/activity-log.mdx) — which operations occurred, when,
and by whom
239 changes: 239 additions & 0 deletions docs/docs/immutable-history/query-historical-data.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
---
title: Query historical data
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

You can query infrastructure data at previous points in time and compare how it changed between

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and compare how the data changed between them.

them. Use queries with a timestamp to investigate incidents, verify changes during a period, answer
audit questions, and inspect how objects and relationships differed at an earlier time.

To query a specific point, specify a branch and timestamp. Infrahub returns the values and

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To query data at a specific point in time, ...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Infrahub returns the object, attribute values and related object that were valid at that time. (I would drop the part about the interfaces you use for current data)

relationships that were valid at that time through the same interfaces you use for current data. To

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To compare changes, specify two timestamps. This is not true, AFAIK. To see the changes between 2 timestamps we actually have to use a dedicated queries.

Also there is a way to get the activity log between 2 given timestamps, to retrieve the audit log.

So I think we should explain here that we have 3 ways to query historical data:

  1. Query the state of the of the database at a given timestamp in a specified branch (using the at and branch query param)
  2. The changes that happened between 2 timestamps in a given branch
  3. The auditrail of what happened between 2 given timestamps in a given branch

compare changes, specify two timestamps.

## Specify a branch and a time

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only relevant in case 1 above


Each query is evaluated for a branch and a point in time. Infrahub uses those two inputs to select
which versions of objects and relationships it returns. If you do not set either one, Infrahub
returns the current data from the default branch.

| State to read | Branch | Time |
|---|---|---|
| Production as it stands | default | now |
| Production during last night's incident | default | a time within the incident |
| The change someone is proposing | their branch | now |
| The default branch just before that change merged | default | a time before the merge |

Queries for earlier data therefore use the same read interfaces as current queries. The difference
is that you specify the time to evaluate the data.

## How historical queries work

When you add a timestamp to a query, Infrahub evaluates each requested object using the attribute
values and relationships that were valid at that time. You use the same query structure as you do
for current data; the timestamp changes which versions Infrahub returns.

Infrahub can return those versions because changes create new attribute values and relationship
versions instead of replacing the previous ones. History is tracked per attribute and relationship,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here as well we should talk about history being tracked per object / attribute and relationship

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually it would be good to point at the explanation you do in the overview page here

so a comparison can identify the specific fields or connections that changed, including the previous

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this part is confusing.

values.

The schema is evaluated for the same point in time. If the schema changed after the timestamp you
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
request, Infrahub loads the schema as it was then, so the query sees the attributes and relationships

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so the query sees the object, attributes and relationship that existed...

that existed at that point rather than the current ones.

A timestamp applies to reads only. If a query document contains a mutation, Infrahub ignores the

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

applies to read operations (query in GraphQL terms) only

timestamp and applies the mutation at the current time.

Once Infrahub records a version, a change made after it does not alter that version. See [Immutable
history](./overview.mdx) for more detail on how Infrahub preserves those versions and how immutable
history relates to branches and the Activity log.

## Query data at a specific time

Use a timestamp when you need the values and relationships that existed at a known point — for

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when you need the objects, attributes and relationships that existed at ..

example, during an incident or before a change.

You can specify a time when viewing or querying Infrahub data through the web interface, GraphQL,
REST API, or Python SDK. Use the web interface for interactive investigation and the APIs or SDK
when you need a repeatable or programmatic query.

<Tabs groupId="method" queryString>
<TabItem value="web" label="Web interface" default>

Select the time selector — the calendar and clock icon beside the branch selector — and choose a
date and time in UTC. Until you set a time, the selector displays only the icon; once you set one,
the bar beside it displays **Current view time** with your selection.

The selected time remains applied as you navigate, so objects and relationships are displayed using
the values valid at that timestamp. Select the × beside the displayed time to return to the current
time.

![The time selector, with a past time applied](../media/tutorial_2_historical.png)

</TabItem>

<TabItem value="graphql" label="GraphQL">

Apply the historical time to the same GraphQL query you use for current data. Use this when you can

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is confusing

I would just say: Use the URL at parameter to specify a desired timestamp in a GraphQL query.

already state the data you need and want a repeatable query.

`at` is a query-string parameter on the endpoint, so the query document itself is unchanged:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at is in fact a URL parameter


```graphql # Read a device as it existed at an earlier time
# Endpoint : http://localhost:8000/graphql/main?at=2026-03-09T14:00:00Z

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The endpoint here is commented out and makes it hard to read in the docs. And in this case the endpoint containing the at URL parameter is exactly the IMPORTANT part.

query DeviceAtTime {
InfraDevice(name__value: "ord1-edge1") {
edges {
node {
name { value }
description { value }
status { value }
}
}
}
}
```

</TabItem>

<TabItem value="rest" label="REST API">

Use the REST API when an external tool, scheduled process, or integration needs data for a specific

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to explain when to use the REST API. We just only offer certain functionality over the REST API, that is not avialable over the GraphQL API. I think it would be better if we just specify which REST API endpoints support this and list them here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IE:
stored graphql queries, artifacts, transfoms...

timestamp. `at` applies to stored GraphQL queries, artifacts, and Transformations rather than to
ad-hoc object reads, so save the query as a `CoreGraphQLQuery` and execute it by name:

```bash
curl "http://localhost:8000/api/query/device-status?branch=main&at=2026-03-09T14:00:00Z" \
-H "X-INFRAHUB-KEY: $INFRAHUB_API_TOKEN"
```

The same parameter applies to `/api/artifact/{artifact_id}` and the transformation endpoints, where
Infrahub renders the artifact from the data that was valid at that timestamp.

</TabItem>

<TabItem value="sdk" label="Python SDK">

Pass the `at` argument to the SDK query methods when you need a node or set of nodes as they existed
at a specific time. `all()`, `get()`, and `filters()` take a `Timestamp`; `execute_graphql()` also
accepts a string.

```python
from infrahub_sdk import InfrahubClient
from infrahub_sdk.timestamp import Timestamp

client = InfrahubClient(address="http://localhost:8000")

device = await client.get(
kind="InfraDevice",
name__value="ord1-edge1",
at=Timestamp("2026-03-09T14:00:00Z"),
)
```

</TabItem>
</Tabs>

## Compare changes between two timestamps

Use a diff when you need to identify which objects or attributes changed between two timestamps.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section will need to be redone. It is not accurate and clear.

We first have to send a mutation to calculate the differences between 2 timestamps (DiffUpdate).
Once the calculation is done, the diff can be retrieved using the DiffTree or DiffTreeSummary queries.

`DiffTree` compares the data at `from_time` with the data at `to_time`. The timestamps do not need
to align with a branch point or Proposed Change, so you can compare any useful period, such as the
four hours around an incident.

```graphql # What changed on main between two timestamps
# Endpoint : http://localhost:8000/graphql/main
query ChangesBetween {
DiffTree(
branch: "main"
from_time: "2026-03-09T00:00:00Z"
to_time: "2026-03-10T00:00:00Z"
) {
num_added
num_updated
num_removed
nodes {
kind
label
status
attributes {
name
action
}
}
}
}
```

Behavior to expect:

- Omit `from_time` and the comparison starts at the branch's `branched_from` timestamp.
- Omit `to_time` and the comparison runs to the present.
- Use `filters` to narrow the result by kind, namespace, or status.
- Use `limit` and `offset` to page through results.
- Use `DiffTreeSummary` when you only need counts rather than the full set of changed nodes.
- The base of the comparison is the default branch. Name a feature branch to compare it with the
default branch across the requested period, or name the default branch to compare it with itself
over time.
- If no diff covering the requested period is available, the query returns `null` rather than an
empty result. Treat `null` as "not calculated," not "nothing changed."

`DiffTree` retrieves a diff that has already been calculated. To calculate one for a period, send
the `DiffUpdate` mutation first with the `branch` and, when you need a period other than the
default, `from_time` and `to_time`. This is why a request for an arbitrary period can return `null`
on the first attempt.

In the web interface, a branch's Branch view shows its diff and lets you refresh it, whether or not

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can also consult a diff for a given proposed change, here we seem to imply we can only do it from the branch page.

a Proposed Change exists for that branch. When you are comparing a branch with its base and also
need review, validation, and checks, use a [Proposed Change](../proposed-changes/overview.mdx).

## Choose an absolute timestamp or relative offset

Use a relative offset when you are investigating from the current time. Use an absolute timestamp
when the query needs to resolve to the same time each time it runs — for example, for an audit
answer, post-incident report, or reproducible analysis.

| Form | Example | Resolves to |
|---|---|---|
| ISO 8601 with a zone or offset | `2026-03-09T14:00:00Z` or `2026-03-09T15:00:00+01:00` | The specified instant |
| ISO 8601 without a zone | `2026-03-09T14:00:00` | The same wall-clock time, interpreted as UTC |
| Date only | `2026-03-09` | 12:00 UTC on that day |
| Offset from now | `30s`, `45m`, `6h`, `2h30m` | That interval before the current time |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is correctly working atm, but that is a different thing


A date without a time resolves to midday rather than midnight, so include an explicit time when a
day boundary matters. Relative offsets support seconds, minutes, and hours, including combined
values such as `2h30m`. They do not support day or week units; use an absolute timestamp for those
intervals.

## Understand branch history limits

You can query a branch back to the point where its history begins. If you request a time earlier
than that, Infrahub rejects the query rather than returning partial data.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This contradicts what we state below. The only exception here is the default branch


When you create a branch, Infrahub records where it diverged rather than copying the entire dataset.
You can query the history available through the default branch, plus the changes recorded on the
branch after it diverged.

On the default branch and the global branch, the earliest available time is that branch's creation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default and global branch are the same thing.

The earliest time you can query in the default branch is the time that you started the application for the first time. I think it will be clearer that way

On any other branch, the boundary is the creation time of the default branch.

```text
Requested time '2026-01-05T00:00:00Z' is before branch 'main' was created at '2026-02-01T09:14:22.481000Z'.
```

If you need data from an earlier timestamp than the branch allows, query the default branch instead.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not needed, because the history from before the branch was created is accessible.


Rebasing a branch moves the timestamps of changes made on it up to the rebase time, so a change

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be part of the overview, not in how we query historical data

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should probably be together with how we explain how merges affect the history

recorded on the branch before a rebase is no longer readable at its original timestamp.

## Related

- [Immutable history](./overview.mdx) — how Infrahub preserves previous values and relationships
- [Branches](../branches/overview.mdx) — how branches diverge, share history, and merge
- [Activity log](../deploy-manage/run-observe/activity-log.mdx) — which operations occurred, when,
and by whom
- [Proposed Changes](../proposed-changes/overview.mdx) — compare a branch with its base with review,
validation, and checks
7 changes: 6 additions & 1 deletion docs/sidebars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,12 @@ const sidebars: SidebarsConfig = {
collapsed: false,
link: { type: 'generated-index', slug: 'branches-and-change-control' },
items: [
{ type: 'doc', id: 'immutable-history/overview', label: 'Immutable History' },
{
type: 'category',
label: 'Immutable History',
link: { type: 'doc', id: 'immutable-history/overview' }, // hub
items: ['immutable-history/query-historical-data'],
},
{
type: 'category',
label: 'Branches',
Expand Down
Loading