Version 0.22.0
New features
Author migration recipes directly on a notice
Notice owners can now record the known fix for a deprecation right on the notice itself — a before/after example, a deterministic codemod, or plain guidance — scoped to a language, file pattern, or repository. Recipes list, add, edit, and retire from a new Migration Recipes section, and a warning appears if a notice's only recipe can't be applied automatically, so you're never left wondering why nothing happened.
See a repository's branch protection before turning on auto-merge
When you set an integration's remediation delivery to "Open pull requests and request auto-merge," the settings page now shows the live branch-protection state of every repository that currently matches your Allowed Repositories pattern — for example, "No required checks configured" or "Required reviews: 2." Previously you only saw static explanatory text about how the top autonomy rung works; now you can see, before turning it on, whether the target repositories actually have branch protection guarding them. Obsolot still never merges anything itself — this is informational, not a gate.
Deterministic codemods render as a runnable invocation in the remediation brief
A migration recipe backed by a deterministic tool (a jscodeshift/ts-morph script, an OpenRewrite recipe, a Roslyn fixer) now renders as a precise, ready-to-run command in the remediation brief — tool, version, and the exact files it applies to — instead of raw configuration. Obsolot never runs the tool itself: your CI or coding agent runs it, and whatever comes back is independently re-verified the same way any other fix is. A recipe with an invalid or missing codemod configuration now fails clearly when it's created, and — for any that slipped through earlier — shows up as a reason on the remediation task instead of silently doing nothing.
Remediation can now open real pull and merge requests
Once a remediation task has a deterministic codemod fix and autonomy allows it, Obsolot now opens an actual branch, commit, and pull or merge request on GitHub or GitLab — instead of only ever describing the change. The description states exactly what changed and what was left out (and why), and links back to the deprecation notice, the campaigns review page, and the repository's badge. Before anything advances further, Obsolot independently re-checks its own verification ladder against what actually landed on the branch — never just the change it generated locally.
Approved and rejected suggestions now teach the recipe for their notice
When you approve a migration suggestion, its before/after fix is now saved as an example onto that notice's own recipe. The automated Remediation agent reads those accumulated examples back when it generates a future patch for the same deprecation — so it starts from what you've already confirmed works. Rejections are remembered too, along with your stated reason when you give one, so the Remediation agent doesn't propose the same rejected fix again. Both build up gradually, capped to keep the most recent and varied examples rather than everything ever seen, and are visible right on the recipe in the notice's Recipes tab.
GitHub/GitLab can now notify Obsolot directly, instead of waiting for the next scan
GitHub and GitLab integrations can now be configured to send Obsolot a webhook on push, so a re-scan starts right away instead of waiting for the next scheduled run. Set it up from the integration's detail page: generate a secret (shown once — copy it before closing the dialog), then add the provided URL and secret to your repository or organization's webhook settings. This is an accelerant, not a replacement — if a delivery is ever missed (a provider outage, a dropped webhook), the scheduled scan still catches it, so nothing is ever silently missed. Every integration starts without a webhook configured; setting one up is opt-in, and the URL, secret, and required event types are all shown together on the setup screen.
Obsolot now comments directly on pull requests that introduce deprecated usages
When a pull or merge request is opened or updated, Obsolot now checks the lines it actually changes against your active deprecation notices and, where autonomy is configured to allow it, leaves a review comment right on the line — a ready-to-apply suggested fix when one is available, or a flag for manual review when it isn't. Each usage only ever gets one comment, and once a reviewer resolves or dismisses it, Obsolot won't bring it up again on that pull request.
Migration recipes drive suggestion authoring
Deprecation notices can now have one or more migration recipes attached — reusable guidance, before/after examples, or codemods scoped to specific languages, files, or package versions. When multiple recipes could apply to the same code reference, the lowest-precedence active recipe wins, and every migration suggestion now records which recipe (if any) produced it so you can see exactly why a suggestion was authored the way it was.
Migration suggestions can now carry a reviewable patch
Migration suggestions can now include a proposed code patch alongside (or instead of) free-text advice. When a suggestion has one, the review UI shows it as a diff you can read and copy, along with the commit it applies to and any verification evidence — rather than a paragraph describing the change. Suggestions without a patch look exactly as they did before.
Source code content sent to AI models is now opt-in and tiered
Every integration now has a "Source-Content Egress" setting that controls how much of your source code the AI agent (built-in or an external MCP client) is allowed to see: nothing by default, just the short stored snippet, live file context on demand, or whole files. Automatic classification needs at least the snippet tier; migration suggestions need live file context. If a task needs more than you've allowed, it's skipped and the reason is shown right on the result — not buried in a log — and the task picks the reference back up automatically once you raise the tier.
If you were already actively using the built-in agent before this release,
nothing changes for you: your existing GitHub/GitLab integrations were set to
whichever tier your enabled tasks actually needed, so classification (and
suggestions, if you had those on) keep working exactly as before. Every new
integration starts closed, and raising the tier is an explicit choice you make
per integration, along with an optional list of file paths (like
**/secrets/**, matched the way .gitignore patterns are) that are never
sent regardless of tier. The current tier is now shown on every integration's
details view, not just in the edit dialog.
Choose a different AI model per agent task
The built-in agent's settings now let you pick a different AI model for each task it performs — for example a cheaper model for classification and a stronger one for generating migration suggestions. Any task left unset keeps using the model you selected as your organization's default.
The AI agent can now propose migration recipes from a deprecation notice alone
Notices that don't yet have a migration recipe no longer have to wait on someone to author one from scratch. The AI agent can now read a notice's own description and linked issues and propose one or more candidate recipes for a maintainer to review — always saved as a draft, never applied automatically. If the notice's description and linked issues don't actually say what the replacement is, the agent says so and flags the notice for its owner instead of guessing.
The AI agent can now write and verify real patches
Beyond classifying usages and suggesting prose fixes, the AI agent can now generate an actual patch for a deprecated usage — reading the surrounding file, applying the deprecation's own migration recipe, and checking its own work before it ever reaches you: does the patch apply, does the deprecated pattern actually go away, and does it avoid introducing another deprecated usage in its place? A patch that doesn't pass those checks is retried automatically within a limited number of attempts; if it still doesn't pass, it's left flagged for your review with the reasons why, rather than being silently discarded or accepted on the model's word alone.
This only runs where a notice has a usable migration recipe. A notice without one is left alone for its owner to supply a migration path, rather than have the agent guess.
An autonomy ladder for remediation delivery
Remediation delivery now climbs a six-rung autonomy ladder — from suggesting a fix, to opening a draft pull request, to requesting the code host's own auto-merge — instead of one blunt on/off switch. The ceiling is set per integration and can be lowered further for an individual notice or repository, and is automatically capped by how risky the applied fix is. Obsolot still never merges a pull request itself: the top rung only asks the repository's own auto-merge feature to do it once that repository's required checks and reviews pass, so the settings page can also show you whether a repository has any of those configured at all.
Claim and deliver remediation work over MCP
An external coding agent (or Obsolot's own built-in agent) can now pick up
and complete remediation work entirely over MCP. GetRemediationBrief hands
over everything needed to act — the notice, the known fix, the exact code
locations, any patch already generated, and the checks your change will be
held to. ClaimRemediationTask and AttachRemediationPullRequest record who
is working on a task and where the resulting pull request landed, so
concurrent agents never collide. ReportRemediationOutcome closes the loop:
Obsolot never simply takes your word that a fix worked — it independently
re-fetches your delivered code and re-runs its own verification before
marking anything Verified. A new "Remediation Tasks" category in the MCP
consent screen and personal-access-token creation dialog lets you scope a
credential to this workflow specifically.
Dispatch remediation work to your platform's coding agent
Obsolot can now open a tracking issue in the target repository for remediation
work, instead of requiring an MCP-connected agent to pick it up. The issue
carries the same brief GetRemediationBrief hands to an MCP agent — what
needs to change and why, the exact code locations, and the checks the fix
will be held to — labeled so a reviewer can always trace it back to Obsolot,
and optionally assigned to your configured coding-agent bot account.
Once a pull request references the issue, Obsolot finds it automatically and re-verifies the change itself before marking the task Verified — the same independent verification the MCP workflow already gets. Nothing here trusts a platform-reported outcome at face value.
Remediation funnel and migration progress dashboard
A new Remediation Dashboard shows, at a glance, whether deprecation cleanup is actually working: how many usages were discovered, classified, patched, delivered, and verified gone, plus resolution rate over time, how long fixes take, how often the AI agent's suggestions are approved, and which notices are approaching their end-of-life date with the least progress. The same figures are available over the GraphQL API for anyone building their own reporting.
Remediation can now dispatch a workflow to run a coding agent
If your organization already runs a coding agent from a GitHub Actions workflow or GitLab CI pipeline, Obsolot can now trigger it directly for a delegated remediation task — in addition to, or instead of, opening a tracking issue. Configure the workflow file (GitHub) or let Obsolot create a pipeline (GitLab), and Obsolot passes along the task id so your workflow knows exactly what to work on.
Remediation campaigns
A new Campaigns page shows how Obsolot is grouping the fixes for each deprecation notice: every affected reference in a repository, on a given branch, bundled into a single campaign rather than scattered one-by-one. Each campaign tracks its own progress — drafted, briefed to an agent, claimed, delivered as a pull request, verified, and merged — so you can see at a glance where a notice's remediation stands across every repository it touches.
Campaigns are read-only for now; nothing is delivered to a code host yet. That follow-up release is next.
Push events now resolve, reopen, and advance remediation work automatically
When a configured GitHub or GitLab webhook reports a push, Obsolot now re-checks only the files that push touched — no more waiting for the next scheduled scan to notice a deprecated usage is finally gone. A reference whose pattern disappeared is marked resolved, with a note of which commit (or scan) resolved it. If a pattern that was resolved reappears later, the reference reopens and its remediation campaign is flagged as regressed, so a premature "fixed" never goes unnoticed. Once every reference in a campaign is resolved, the campaign is automatically marked verified. The scheduled full scan keeps running as a safety net for anything a webhook delivery misses.
Write-capable code-host integrations, with a kill switch
GitHub and GitLab integrations can now be configured to deliver remediation
work back to your code host — not just suggest it inside Obsolot. A new
"Remediation delivery" setting lets you choose how far Obsolot may go, from
suggestions only up through opening ready-for-review pull requests and
requesting your platform's own auto-merge; every level above the first
requires a write-capable credential, and Test Connection will tell you if
yours isn't one. You control which repositories are ever eligible (glob
patterns, so my-org/* covers a whole organization or you can list
repositories one at a time), who gets requested as a reviewer, and four caps
that limit the blast radius: how many pull requests can be open at once per
repository, how many can open per day, and how large any single pull request
is allowed to get.
Every organization starts closed — nothing is delivered anywhere until you opt an integration in. A new kill switch on the Integrations page stops all remediation delivery for the whole organization immediately, including work already queued, for when you need to pause everything at once.
Nothing can be opened on a code host yet — this release wires up the configuration, the safety caps, and the kill switch. Actual delivery lands in a follow-up release.
Improvements
Code reference links now point to the exact commit, not the branch tip
Discovered code references now record the commit they were found at. Reference links in the UI open the file as it looked at that commit instead of the current default branch, so the link stays correct even after the file moves or changes later. References found before this change keep working exactly as before.
The GitGud integration has been removed
GitGud has shut down, so the integration that synced deprecation notices from it is gone. If you had one configured, the integration and its stored credentials are removed when you upgrade.
Any notices that had been synced from GitGud are kept. They become ordinary notices owned by your organization, which you can now edit freely — previously a sync could overwrite them.
Bug fixes
The AI agent now actually files its findings
If you had the AI agent enabled, it was reviewing your code references and then quietly dropping the results: the agent activity page filled up with runs, but no reference ever got classified and no migration suggestion ever appeared. The agent could not write anything back.
It can now. Scheduled and on-demand runs classify references as true or false positives and file migration suggestions into the review queue, attributed to the agent so you can tell its work from a person's. Each run also records every action the agent took, so you can see exactly what it did and why.
Nothing about review changes: suggestions still arrive as Pending and wait for a human, and low-confidence results are still held for review.
Fixed possible duplicate or missing rows when paging the Agent Activity log
When many activity log entries were recorded at the same instant (for example, after enabling a stricter source-content egress tier skips a large batch of code references in one run), paging through the Agent Activity log could show a duplicate entry on one page and miss another entirely. Paging is now stable in every case.
Fixed focus not returning to the Add Recipe button after closing the dialog
Closing the Add/Edit Recipe dialog on a notice's Migration Recipes section — via Escape, the close button, Cancel, or successfully saving — now returns keyboard focus to the button that opened it (or a sensible fallback if that button no longer exists), instead of dropping it to the top of the page.
Fixed the Agent Activity page failing to load with a status or search filter applied
The Agent Activity page failed to load with an error whenever a status filter, search term, or date range was applied. It now loads correctly with any combination of filters.
The What's New feed now loads
The "What's New" dialog now actually loads Obsolot's release notes, and the version number at the bottom of the sidebar becomes a clickable link to the full history. A configuration issue was silently blocking the connection to our website, so both always appeared empty before — you'll now see what's changed since your last visit.
Fixed focus not returning to the Add Integration button after closing the dialog, and made integration rows keyboard-operable
Closing the "Add Integration" dialog or an integration's detail dialog in Organization Settings — via Escape, the close button, or completing the action — now returns keyboard focus to the button or row that opened it (or a sensible fallback if it no longer exists), instead of dropping it to the top of the page. Integration rows can now also be opened with the keyboard (Tab to focus, Enter or Space to open) — previously they were only clickable with a mouse.
Fixed a heading-hierarchy issue in the Integrations dialog
Screen reader users navigating the Integrations section of Organization Settings by heading level would land on a second page-level heading nested under the dialog's own title. The Integrations list, Add Integration, and integration detail pages now correctly render their titles as section-level headings within the dialog, consistent with the rest of Organization Settings.
Fixed the migration suggestion review panel failing to load
The migration suggestion review panel (and the equivalent REST endpoint) failed to load with an error whenever suggestions were filtered by code reference and sorted by creation date — which was every time. It now loads correctly.
Fixed the notice title being obscured by the status badge on mobile
On the Notice Detail page, viewing a notice on a narrow screen (e.g. a phone) could show the status badge overlapping the first word of the notice title. The header now stacks the title above the status and action controls at narrow widths instead of overlapping them.
Notices list no longer hides Draft notices behind a default "Active" filter
The Notices list page previously defaulted its Status filter to "Active" only, which made organizations with only Draft notices see a misleading "no notices found" message. The list now shows notices of all statuses by default; you can still narrow to a specific status using the Status filter.
Fixed a skipped heading level on the Notices, Repositories, Templates, and Labels list pages
Screen reader users navigating by heading level on the Notices, Repositories, Templates, and Labels pages would jump from the page title directly to a lower heading level, skipping a level in between. Card titles and empty-state messages on these pages are now one level below the page title, so the heading outline is sequential.
Fixed a brief "No organization selected" flash on page reload
Hard-reloading or opening a bookmarked/shared link to an organization page (repositories, notices, templates, labels, badges, integrations, agents, and their detail/create/edit variants) could briefly show a "No organization selected — please select one from the sidebar" message, even though the organization was already known from the URL. The page would then correct itself a second or two later once the organization finished loading.
That message now only appears when there really is no organization to select. While the organization is still loading, the page shows a neutral loading placeholder instead, so a normal page load no longer looks like an error.
Fixed the "New organization" button overflowing on mobile
On the Organizations page, viewing the list on a narrow screen (e.g. a phone) could push the "New organization" button past the edge of the screen with its label clipped. The header now stacks the title above the button at narrow widths instead of overflowing.
Fixed an orphan heading on the "No organization selected" fallback state
Screen reader users navigating by heading level on any org-scoped page would,
while no organization was selected, land on a heading with no page title
before it. The "No organization selected" message is now marked up as the
page's <h1>, consistent with the page's own title once an organization is
selected.
Remediation Dashboard charts now have accessible names and hidden data tables
The Remediation Dashboard's charts (funnel, campaign pipeline, resolution rate over time, time-to-resolution distribution, and verification rungs) previously exposed no data to screen readers. Each chart now has an accessible name summarizing its current values, plus a hidden data table with the full dataset.
Fixed skipped heading levels on the Campaigns, Agent Activity, Remediation Dashboard, Badges, and Integrations pages
Screen reader users navigating by heading level on the Campaigns, Agent Activity, Remediation Dashboard, Badges, and Integrations pages would jump from the page title directly to a lower heading level, or land on a visible section title with no heading markup at all. Section titles, filter panel labels, and empty-state messages on these pages now form a sequential heading outline, matching the fix already applied to the Notices, Repositories, Templates, and Labels pages.
Fixed the Repository Detail page incorrectly showing "Repository not found"
Clicking a repository from the Repositories list could land on a "Repository not found" page even though the repository had active code references — this happened for repositories whose integration has no configured base URL (the common case for default GitHub/GitLab integrations). The Repository Detail page now resolves correctly in this case.
Added a "Skip to main content" link for keyboard and screen-reader users
Keyboard and screen-reader users previously had to tab through the entire sidebar navigation on every page before reaching page content, with no way to bypass it. A "Skip to main content" link — hidden until it receives keyboard focus — now appears as the first focusable element on every page and jumps straight to the page content.
Syntax-highlighted Exemplar recipe code
Before/After code examples on an Exemplar migration recipe now render with language-aware syntax highlighting (keywords, identifiers, and literals visually distinguished) instead of plain unstyled text, using the recipe's configured language.