<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Stanislav Sysoiev</title>
    <description>The latest articles on DEV Community by Stanislav Sysoiev (@sysstas).</description>
    <link>https://dev.to/sysstas</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F270981%2F3b6b0014-7e2c-4ccd-8a24-2bdec107a6f0.png</url>
      <title>DEV Community: Stanislav Sysoiev</title>
      <link>https://dev.to/sysstas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sysstas"/>
    <language>en</language>
    <item>
      <title>Before your AI agent edits Linear, test how you will recover</title>
      <dc:creator>Stanislav Sysoiev</dc:creator>
      <pubDate>Sat, 14 Nov 2026 20:19:28 +0000</pubDate>
      <link>https://dev.to/sysstas/before-your-ai-agent-edits-linear-test-how-you-will-recover-17cl</link>
      <guid>https://dev.to/sysstas/before-your-ai-agent-edits-linear-test-how-you-will-recover-17cl</guid>
      <description>&lt;p&gt;“Clean up the backlog” sounds like a small task until you have to define &lt;em&gt;clean&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Does an issue with no updates for six months need closing? What if it describes a security problem? Are two similar titles duplicates if they affect different customers? Can an agent shorten a description without dropping the one reproduction step that matters?&lt;/p&gt;

&lt;p&gt;Imagine an agent closes 40 issues and rewrites 12 descriptions. Some changes are useful. Others are wrong. Meanwhile, a teammate adds a comment and updates an assignee.&lt;/p&gt;

&lt;p&gt;Now you need to recover the wrong changes while keeping the useful ones and your teammate's work.&lt;/p&gt;

&lt;p&gt;That's a hypothetical example, but it's the question I would answer before enabling bulk edits. I build BackupLatte, a backup service for Linear and ClickUp, so my interest here is also practical: what can you actually recover after a tool has changed your data?&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with a proposal you can inspect
&lt;/h2&gt;

&lt;p&gt;For a first run, give the agent a task that ends with a proposed change list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Review open issues in the ENG team that have not been updated
in the last 180 days. Do not modify anything.

For each candidate, show:
- the issue identifier and URL
- its current status
- the proposed status
- the evidence for making that change
- anything that makes the decision uncertain

Exclude issues in active projects and issues with unresolved
dependencies. List possible duplicates separately; do not merge
or delete them. Return at most 10 candidates, then stop.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact rules should come from your team. The useful part is that you can inspect individual decisions before they become writes.&lt;/p&gt;

&lt;p&gt;For that initial review, enforce read-only access in the connection. Linear offers an MCP endpoint at &lt;code&gt;https://mcp.linear.app/mcp/readonly&lt;/code&gt; that exposes only read tools. Its standard endpoint can also be used with only the &lt;code&gt;read&lt;/code&gt; OAuth scope. &lt;a href="https://linear.app/docs/mcp" rel="noopener noreferrer"&gt;Linear's MCP documentation&lt;/a&gt; describes both options.&lt;/p&gt;

&lt;p&gt;A sentence saying “do not modify anything” helps communicate intent. A read-only connection also prevents a write if the agent gets that instruction wrong. Check for other connected tools or credentials that could still give it write access.&lt;/p&gt;

&lt;p&gt;When you enable writes, keep the permissions narrow. Linear personal API keys can be restricted by permission and team. For an OAuth integration that only posts comments, &lt;code&gt;comments:create&lt;/code&gt; is available instead of broad &lt;code&gt;write&lt;/code&gt; access. These are different connection mechanisms; check the one your agent actually uses. &lt;a href="https://linear.app/docs/api-and-webhooks" rel="noopener noreferrer"&gt;API keys&lt;/a&gt; · &lt;a href="https://linear.app/developers/oauth-2-0-authentication" rel="noopener noreferrer"&gt;OAuth scopes&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Approve specific changes, then check that they are still current
&lt;/h2&gt;

&lt;p&gt;“Those suggestions look good” is a weak handoff if the next run searches the backlog again and generates a different list.&lt;/p&gt;

&lt;p&gt;Keep a record of the approved operations. For a status change, it could look like this illustrative record:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;"issue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ENG-142"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nl"&gt;"field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nl"&gt;"before"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Backlog"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nl"&gt;"after"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Canceled"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nl"&gt;"reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Superseded by ENG-201; confirmed by the owner"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a review record, not a Linear API request. An executor would resolve and use the actual issue and workflow-state IDs.&lt;/p&gt;

&lt;p&gt;Before applying it, read the issue again. If its relevant fields have changed since approval, skip it and ask for another review. A preflight read reduces the chance of overwriting newer work, although it cannot eliminate a race between that read and the write.&lt;/p&gt;

&lt;p&gt;If you control the integration, enforce the approved issue list, permitted fields, and batch size in code. If you only control an agent prompt, treat those limits as instructions whose enforcement you still need to verify.&lt;/p&gt;

&lt;p&gt;Start with a small batch. Save the old values, the attempted operations, and their outcomes somewhere the editing agent cannot modify. A list of successful requests alone won't tell you what to put back.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rehearse recovery in a separate workspace
&lt;/h2&gt;

&lt;p&gt;Before trying a bulk cleanup on the live backlog, make a disposable test workspace with a few representative issues. Use synthetic or sanitized content if real tickets contain sensitive information.&lt;/p&gt;

&lt;p&gt;Include cases where a simple rule should fail: an old but important issue, two similar titles that aren't duplicates, a parent with an unresolved sub-issue, and a description containing an essential attachment.&lt;/p&gt;

&lt;p&gt;Then run a small recovery exercise:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Save the starting state and confirm you can read it back.&lt;/li&gt;
&lt;li&gt;Run the agent's proposed task against the test workspace.&lt;/li&gt;
&lt;li&gt;Add a legitimate human edit after the run.&lt;/li&gt;
&lt;li&gt;Recover a wrong status change, an overwritten description, and a deleted test issue using the recovery methods you intend to rely on.&lt;/li&gt;
&lt;li&gt;Check that the legitimate edit and relevant relationships or files survived.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Record how long this takes and which steps need a person. If you are testing a restored copy of real data, check what your restore tool actually carries over; a copy may have different identifiers, users, permissions, or missing features.&lt;/p&gt;

&lt;p&gt;The point of this exercise is to discover those differences while nobody is waiting for their backlog to work again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recovery depends on what changed
&lt;/h2&gt;

&lt;p&gt;Once you discover a bad run, stop further writes first. Revoke the relevant credential or integration authorization, and stop the running automation. Disconnecting a client is only sufficient if that actually removes its ability to keep writing.&lt;/p&gt;

&lt;p&gt;Then separate the damage:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What happened&lt;/th&gt;
&lt;th&gt;What to check before repairing it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Statuses, labels, or assignees changed&lt;/td&gt;
&lt;td&gt;Compare saved values with current values. Preserve any legitimate edits made afterward.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Descriptions were overwritten&lt;/td&gt;
&lt;td&gt;Retrieve the earlier text and merge back the missing content.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Issues were deleted&lt;/td&gt;
&lt;td&gt;Check Linear's Recently deleted items first.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unwanted issues or comments were created&lt;/td&gt;
&lt;td&gt;Identify the specific new records and review their removal.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Linear retains recently deleted issues for 30 days, and its documentation describes restoring them from the team's archives. That gives you a recovery path for deletion; it doesn't undo unrelated field edits or identify unwanted new records. &lt;a href="https://linear.app/docs/delete-archive-issues" rel="noopener noreferrer"&gt;Linear's deletion and recovery documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This distinction matters when choosing a backup tool, too. Ask what its Restore button does to an existing record whose description has changed.&lt;/p&gt;

&lt;p&gt;In BackupLatte, restoring into the original Linear workspace recovers supported missing records and reuses matching existing ones. It &lt;strong&gt;does not overwrite existing records to roll back their fields&lt;/strong&gt;. For overwritten text, you can consult a downloaded snapshot or a copy restored into another workspace, then bring back what you need. The &lt;a href="https://backuplatte.com/docs/restore?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=ai_agent_recovery" rel="noopener noreferrer"&gt;restore guide&lt;/a&gt; explains the behavior and limitations.&lt;/p&gt;

&lt;p&gt;A snapshot also has to predate the mistake and remain available when you discover it. Check its timestamp, coverage, and retention before a consequential run.&lt;/p&gt;

&lt;h2&gt;
  
  
  The question to answer before the first write
&lt;/h2&gt;

&lt;p&gt;Pick one proposed change and ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If this is wrong, where is the previous value, who can recover it, and how will we preserve work done afterward?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you can demonstrate the answer in a test workspace, you have a concrete basis for letting the agent make a small batch of real changes.&lt;/p&gt;

&lt;p&gt;How are you handling this in your team: read-only suggestions, approval for each batch, or autonomous edits with a recovery process you've tested?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devops</category>
      <category>iot</category>
      <category>mcp</category>
    </item>
  </channel>
</rss>
