Changelog
All notable changes to Mari, the self-hosted product knowledge platform, are documented here. The format follows Keep a Changelog, and the project aims to follow Semantic Versioning.
Unreleased
0.2.0 - 2026-09-02
Helm chart 0.2.0. Nine additive migrations (0028 through 0036) run on first start. The first scheduled sync after the upgrade is a full reconcile for every source. This release is not downgradable past 0.1.3 without a pre-upgrade backup.
Security
- Admin and manager rights come from project membership, not from a global account role. A person can be an admin in one project and a viewer in another. Invitations join with the invited tier.
- Deactivated accounts cannot sign in with a password, matching the OAuth and OIDC paths.
- Public knowledge-chat sessions carry an unguessable token, so a visitor cannot continue another visitor's conversation by guessing an id. The endpoint is rate limited per IP and per destination, with a daily budget.
- GraphQL is bounded in depth, aliases and size, and server errors no longer reach the client with SQL in them.
- The GitHub
@marimention fires only for repository owners, members and collaborators, at most three runs per pull request per hour, and pull request text is handled as evidence, never as instructions. - MCP bearer tokens are stored hashed only; the migration hashes and blanks any remaining plaintext token.
- Forwarded headers are trusted only from configured proxies
(
MARI_TRUSTED_PROXIES: an address, a CIDR, or*), read from the nearest proxy inward. The chart's nginx forwards the ingress protocol so session cookies are marked Secure behind TLS. - Every source's config is masked in the console, including rows a retired mutation left without a connector.
/metricscan be gated withMARI_METRICS_TOKEN.
Added
- Restore an invalidated fact. Invalidation is no longer a one-way door: Restore reopens the claim as needs-review, the invalidation event stays in the history, and a person re-verifies deliberately.
- Facts remember when they were captured. The ledger's date column shows the verification date, or the capture date for unverified claims, so a fresh claim no longer renders dateless.
- One filter bar across the console. Facts, Decisions, Lineage and Workflows share the same controls in the same order: search, then Status, Owner and a date range. Status filters are dropdowns with live counts, and a view narrowed to nothing names the filters doing it and offers Clear filters.
- New task on Scheduled tasks. Fact extraction or the digest can be put back on a cadence after a removal, from the page's own header.
- Upload files from the Uploads card. Adding documents no longer requires the onboarding flow; the card that holds them takes more.
- Reconnecting a provider adopts its kept documents. A source removed with its documents kept used to duplicate the whole set on reconnect; the snapshot is now re-adopted, when the provider has exactly one connection.
- Sync rows offer sub-hourly cadences on Scheduled tasks, the same options Sources sets, so a 10-minute sync is a real choice there rather than a value you could leave but never return to.
-
Credential help links out. A setup field whose help names a URL, like the Atlassian API token page on the Confluence and Jira screens, renders it as a link.
-
Fact scans, on a schedule. Scan facts extracts candidate claims from indexed documents. The configuration picks sources, filters, and how many claims per document, and every model-backed stage carries a hard budget of calls and tokens. A scan can run once or on a cadence from hourly to weekly.
- Staged fact review. Extracted claims land as candidates attached to the run, not in the facts table. Work the queue by hand, let a bounded model pass propose verdicts for you to confirm, or let it apply its high-confidence proposals while uncertain candidates wait for you. Accepted claims publish as needs-review or verified, your choice, and every verdict stays on record.
- Impact before invalidation. A fact row's Impact view shows the embedding-space neighborhood of related facts and evidence, with each relation marked as supporting, contradicting, or sourcing the claim. High-impact facts are flagged in the table, and invalidating one preserves its history.
- Scheduled tasks. Schedule-capable workflows now live on one page: cadence, last run, next run, pause and resume (pausing keeps the cadence), run now, and remove. Connector syncs are listed here too, and Sources keeps its per-source schedule control.
Changed
- Fact scans work with local models. Each extraction call gets the token budget the recipe needs instead of an even slice that truncated every answer, timeouts defer documents to the next run instead of failing it, and facts a person accepts are owned by that person, with a human adoption taking a fact over from the automation.
- Scans read as alive. The run card appears on click, the progress bar pulses and names the executing stage, and a failed scan offers Retry with its stored settings. Scheduled tasks update while a run finishes instead of reading "running" until something else refreshes the page.
-
Destructive confirms say what the press does. "Confirm remove" instead of "Really remove?", with a visible Cancel beside every armed confirm. Wide tables gained edge paddles for panning without the bottom scrollbar.
-
Removing a source now asks about documents. The remove dialog offers a choice: delete the indexed documents with the source, or keep them.
- Retrieval reads from versioned chunk embeddings. Rotating the embedding model adds a profile instead of overwriting vectors, so older retrieval artifacts stay reconstructible, and stale profiles are refreshed at startup.
Fixed
- The weekly digest survives a citation the model got wrong: the citation drops, the topic stays, and Home's changes count now includes fact work, not only document edits.
- The date-range filter uses the reader's local days on both sides of the comparison, so a fact captured in the evening no longer falls out of a range that visibly includes it.
- A freshly connected source's card appears immediately; connect and upload used to leave the open page stale until a reload.
-
A sync no longer fails with "Table already exists" when two servers shared one catalog, and the error that remains names the real mismatch.
-
Dismissing a workflow run now sticks. Dismissed runs stay hidden for you across reloads instead of resurfacing.
- A run waiting on review survives a workflow upgrade. When the pipeline gains a stage, the waiting run realigns to it instead of starting over.
- A Slack sync configured with channels the app cannot access now fails and
names them, with the fix spelled out (invite the app, reinstall with
groups:readandgroups:history), instead of reporting a healthy sync with zero documents forever. Channels can also be configured by channel ID, which survives renames. - A new Confluence connection no longer stops at exactly 2,000 pages and waits for the next scheduled run. The per-run budget for Confluence now covers up to 10,000, with anything beyond that picked up by the next run.
- Slack checks channel access when you test or save the connection, so the "invite the app" answer arrives before the source exists. Channel IDs are resolved directly, archived channels are named as archived, and a workspace with more channels than were scanned says so.
- A source left behind by the retired connectSource mutation can be removed. Sync, resync, edit and pause on such a row refuse with a plain message instead of writing into it.
- Cancelling the fact-scan dialog is a no-op, not an error. The dialog is a real modal: focus goes in, Tab stays inside, Escape and the backdrop cancel, focus comes back.
- The knowledge chat shows only the sources an answer cites, and none for a refusal, whether the model uses the exact sentence or paraphrases it. A fenced or indented fallback is unwrapped. Confluence pages built in the new editor no longer leak panel attributes into the text.
- A source's config is written under a row lock, one writer's keys at a time, so the scheduled sync, the Confluence and Drive webhooks, and the Slack bot stop undoing each other's checkpoints. Pausing during a sync sticks. A provider rate limit mid-sync retries and reports as backfilling instead of failing the run.
- Every source reconciles in full once a day (
full_every_hourson the sync flow, default 24), so records deleted at the provider leave the index. A throttled full pass is not recorded as complete. - Workflow runs carry a heartbeat. A run that dies mid-flight is failed and its schedule resumes; an approved or queued run keeps its lease, and a swept run cannot resurrect itself.
- Anthropic chat streaming raised on every turn.
- A refreshed Google Drive token is persisted, so watch renewals stop failing after an hour.
- Adding a fact that differs only in case from an existing one says so instead of reporting success.
- Prefix search works again: "auth" finds "authentication".
- The readiness probe borrows a pooled connection with a one-second timeout and answers 503 when the pool is saturated, instead of taking the pod unready.
- SCIM and MCP requests reach the API when the web image fronts it; they used to fall through to the console shell.
- Large first syncs were quadratic: the canonical store rescanned every document version per page.
2026-08-27
Added
- Remove a source for real. Connector cards have a Remove action that deletes the source, its indexed documents, and its sync schedule after a confirm. Disconnect keeps its meaning: pause syncing, keep everything.
- Multiple connections per provider. Two Confluence sites or two Slack workspaces are two sources. The catalog lists each connection by name and offers Add another, and an optional display name at connect time keeps siblings apart.
- Edit connection. A stored setting, a space key or a rotated token, can be corrected on the card without disconnecting. Blank secrets keep their stored values, and saving starts a full resync.
- A Helm chart with every release.
mari-<version>.tgzis attached to each GitHub release, digest-pinned to that release's public images.
Fixed
- Reconnecting a disconnected source works. It used to fail with "already connected", leaving no way to correct a bad setting.
- Connecting an already-connected source names the source in the way and offers to open it for editing, instead of a dead-end error.
- Failed syncs show the reason the connector reported, on the card.
2026-08-22
Added
- Workflows replaces the Trajectories and Answers pages. Observed is every run the agent harvested out of a chat turn, Approved answers is the library those runs are promoted into, and a run can now be promoted to an answer in place. Old
/trajectoriesand/answerslinks redirect to/workflows. - One chat style across every surface. The console dock, a public knowledge chat, and the Slack bot all write to the same style guide: answer first, cite every claim from the retrieved context, and say so in one sentence when the sources do not cover it.
- GitHub fact-check on demand. The bot fires on a bare
@marimention in a pull request or an issue comment, or on themari:factchecklabel, and replies in the thread.
Changed
- Chat answers render as Markdown, with the documents behind them listed in a Sources block under the answer rather than inline.
- Lineage navigates. Breadcrumbs track where you are, the node cap is stated honestly as "showing N of M" with a control to raise it, groups expand in place instead of replacing the graph, the layout no longer collides and spreads as you zoom in, and search offers a dropdown of matching nodes.
- Jira connector ported to the new search API.
Removed
- The Review and Flows pages. Sync cadence is now a per-source schedule on Sources.
Open source launch
Mari is now open source under Apache 2.0.
Added
- Self-hosted by design. Mari runs on your infrastructure. Postgres with pgvector is the whole data plane for storage and search, and local models run through ollama. Every LLM feature has a deterministic fallback, so the product works with the model off.
- 14 connectors feeding one ingestion pipeline, including GitHub (files, commits, PR descriptions, issues, and comments) and Slack. GitHub webhooks trigger live re-syncs, and unchanged content is never re-embedded.
- Facts with a record. Every fact carries an owner, a verification status, and a freshness date. Answers stream with numbered citations back to the document, commit, or thread they came from.
- Lineage graph tying documents, commits, PRs, and decisions together through structural and semantic links.
- Drift audit. A repo audit scans connected repositories for documentation drift and offers one-click fixes, and the agent can tag drift.
- Publishing. Turn curated, tagged documents into a deployed docs site with the native generator or Docusaurus.