<?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: Kravtsov</title>
    <description>The latest articles on DEV Community by Kravtsov (@sergii-kravtsov).</description>
    <link>https://dev.to/sergii-kravtsov</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%2F4019716%2F02f3c639-7009-4ec3-9ab0-2684eabbbfde.jpg</url>
      <title>DEV Community: Kravtsov</title>
      <link>https://dev.to/sergii-kravtsov</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sergii-kravtsov"/>
    <language>en</language>
    <item>
      <title>What your wiki needs before an AI assistant can onboard a new hire</title>
      <dc:creator>Kravtsov</dc:creator>
      <pubDate>Wed, 07 Oct 2026 20:16:04 +0000</pubDate>
      <link>https://dev.to/sergii-kravtsov/what-your-wiki-needs-before-an-ai-assistant-can-onboard-a-new-hire-31i0</link>
      <guid>https://dev.to/sergii-kravtsov/what-your-wiki-needs-before-an-ai-assistant-can-onboard-a-new-hire-31i0</guid>
      <description>&lt;p&gt;A new salesperson asks the wiki whether she can give 25% off an annual plan. The answer says no, names the person who approves it, and links to the page it came from. Nobody was interrupted.&lt;/p&gt;

&lt;p&gt;I'm the CEO of Evergreen, and we build Folio, an open-source wiki where every page is a file in Git. This is how its onboarding setup works, shown on a made-up Sales space: Acme, a new hire called Jamie, a manager called Marcus. &lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/T4JXTNRrsMg" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The answer is not the interesting part. What the wiki needs underneath it is.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Pages are files&lt;br&gt;
A document is *.md, a table is *.table.md, a form is *.form.md, all inside a Git repository. PostgreSQL keeps the index and the access rules, not the content. The assistant, an IDE and a human in the browser work with the same files, and every change is a commit with an author.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ask mode answers from pages, and the sources are a rule&lt;br&gt;
Folio AI is a panel with two modes. Ask is read-only, and that is enforced on the server. Agent can also write.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqxyd9hmyankkj28nn0tl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqxyd9hmyankkj28nn0tl.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ask mode. The Sources: line is a link to the page, and one click opens it.&lt;/p&gt;

&lt;p&gt;That last line is not magic. Without a rule the assistant only has to name the space and the page. The Sources: line with links is a page in the space's .agent folder. This is the starter we ship, how-to-answer.md:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How to answer&lt;br&gt;
You help a new teammate in their first weeks. Answer from the pages of this space, not from general knowledge.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search the space before you answer. Read the page, do not guess from its title.&lt;/li&gt;
&lt;li&gt;Keep the answer short: two to five sentences, or a short list when the answer is a sequence of steps.&lt;/li&gt;
&lt;li&gt;Always end with a line &lt;code&gt;Sources:&lt;/code&gt; followed by links to the pages you used, in the form &lt;code&gt;[Page title](/s/&amp;lt;space&amp;gt;/p/&amp;lt;id&amp;gt;)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Say plainly when the pages do not contain the answer. Do not make up prices, dates, names or rules. Then suggest who to ask, using the page "Escalation".
.agent is a folder of ordinary pages that only space administrators can see or edit. Everything in it goes into the context of every run in that space, in Ask and Agent mode, up to about 60,000 characters. For a non-admin those pages simply do not exist: the answer is "page not found". The panel shows ".agent rules (1)" above the input.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;A rule is a line of text, and Git remembers it&lt;br&gt;
The manager adds one line to the page:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Before the Sources line, add a line "Next step:" with one concrete action.&lt;br&gt;
Then he asks the same discount question in a new conversation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fql39yvcvyt37ka33cgv6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fql39yvcvyt37ka33cgv6.png" alt="Rule modification"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The rule applies from the next conversation: an old one keeps its earlier turns in the Cursor SDK. And rules are pages, so they have page history: who added "Next step", when, and a restore button, like any other page.&lt;/p&gt;
&lt;h2&gt;
  
  
  A form is a table with a front door
&lt;/h2&gt;

&lt;p&gt;At the end of the week the newcomer answers five questions. That is a form page, paired one to one with a table: a form field is a table column.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo3d67nc9g4bwxuieyztl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo3d67nc9g4bwxuieyztl.png" alt="Table"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is what Folio writes to disk. It is the demo's "Feature requests" table (columns and rows trimmed), serialized by the repository's own codec:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;folio&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;table&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;01J00000000000000000000T01&lt;/span&gt;
&lt;span class="na"&gt;columns&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;title&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;What do you want?&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;text&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rating&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;How much do you need it (1 to 5)&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;number&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;contact&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;You may contact me&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;checkbox&lt;/span&gt;
&lt;span class="na"&gt;views&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
&lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;rowIds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;none&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="c1"&gt;# Feature requests&lt;/span&gt;

&lt;span class="s"&gt;&amp;lt;!-- folio:table:begin --&amp;gt;&lt;/span&gt;

&lt;span class="pi"&gt;|&lt;/span&gt; &lt;span class="err"&gt;What&lt;/span&gt; &lt;span class="err"&gt;do&lt;/span&gt; &lt;span class="err"&gt;you&lt;/span&gt; &lt;span class="err"&gt;want?&lt;/span&gt; &lt;span class="err"&gt;|&lt;/span&gt; &lt;span class="err"&gt;How&lt;/span&gt; &lt;span class="err"&gt;much&lt;/span&gt; &lt;span class="err"&gt;do&lt;/span&gt; &lt;span class="err"&gt;you&lt;/span&gt; &lt;span class="err"&gt;need&lt;/span&gt; &lt;span class="err"&gt;it&lt;/span&gt; &lt;span class="err"&gt;(1&lt;/span&gt; &lt;span class="err"&gt;to&lt;/span&gt; &lt;span class="err"&gt;5)&lt;/span&gt; &lt;span class="err"&gt;|&lt;/span&gt; &lt;span class="err"&gt;You&lt;/span&gt; &lt;span class="err"&gt;may&lt;/span&gt; &lt;span class="err"&gt;contact&lt;/span&gt; &lt;span class="err"&gt;me&lt;/span&gt; &lt;span class="err"&gt;|&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; --- | --- | --- |&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; Dark theme for the table grid | 3 | [x] |&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; PDF export of whiteboards | 4 | [ ] |&lt;/span&gt;

&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="s"&gt;!-- folio:table:end --&amp;gt;&lt;/span&gt;
&lt;span class="err"&gt;A&lt;/span&gt;&lt;span class="s"&gt;nd the form that fronts it:&lt;/span&gt;

&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="s"&gt;--&lt;/span&gt;
&lt;span class="err"&gt;f&lt;/span&gt;&lt;span class="s"&gt;olio: form&lt;/span&gt;
&lt;span class="err"&gt;v&lt;/span&gt;&lt;span class="s"&gt;ersion: 1&lt;/span&gt;
&lt;span class="err"&gt;i&lt;/span&gt;&lt;span class="s"&gt;d: 01J00000000000000000000F01&lt;/span&gt;
&lt;span class="err"&gt;t&lt;/span&gt;&lt;span class="s"&gt;able: handbook/feature-requests.table.md&lt;/span&gt;
&lt;span class="err"&gt;t&lt;/span&gt;&lt;span class="s"&gt;itle: Request a feature&lt;/span&gt;
&lt;span class="err"&gt;p&lt;/span&gt;&lt;span class="s"&gt;ublic: false&lt;/span&gt;
&lt;span class="err"&gt;s&lt;/span&gt;&lt;span class="s"&gt;ubmitButton: Send request&lt;/span&gt;
&lt;span class="err"&gt;f&lt;/span&gt;&lt;span class="s"&gt;ields:&lt;/span&gt;
  &lt;span class="s"&gt;- columnId: title&lt;/span&gt;
    &lt;span class="s"&gt;label: What do you want?&lt;/span&gt;
    &lt;span class="s"&gt;required: true&lt;/span&gt;
    &lt;span class="s"&gt;kind: text&lt;/span&gt;
  &lt;span class="s"&gt;- columnId: rating&lt;/span&gt;
    &lt;span class="s"&gt;label: How much do you need it (1 to 5)&lt;/span&gt;
    &lt;span class="s"&gt;required: true&lt;/span&gt;
    &lt;span class="s"&gt;kind: number&lt;/span&gt;
&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="s"&gt;--&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The table is plain GitHub-renderable Markdown, so a new answer is a diff. The server adds Submitted at and Submitter itself. Anyone with the viewer role or higher can submit while signed in; anonymous answers need the public flag and a share link, both. The answers table can be restricted to the manager: the newcomer's submission still lands, and he cannot read the table.&lt;/p&gt;

&lt;h2&gt;
  
  
  Views are the manager's inbox
&lt;/h2&gt;

&lt;p&gt;A view is a filter with and/or rules and a sort, stored in the table's front matter. "Needs a follow-up" in the video is an or: the discount ceiling answered is not 10, or the readiness score is 2 or lower. Four rows go in, one stays: the person who wrote 15.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpus4rlrycbnvqax7whsw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpus4rlrycbnvqax7whsw.png" alt="Inbox"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The assistant reports what it could not answer
&lt;/h2&gt;

&lt;p&gt;This is the part I would build first. There are three signals, and none asks anyone to fill in a report: a 👍 or 👎 on each saved answer, a survey ("Did the assistant solve your question?") after every third answer, and a built-in tool the assistant calls itself.  &lt;/p&gt;

&lt;p&gt;The assistant calls it once per question, and the server enforces that: check and insert run under a per-run advisory lock, questions are compared after normalization, a duplicate inside one run is dropped (it only fills an empty missing), and a run keeps at most three reports. The missing field is rendered as Markdown, and the tool description requires links to the pages the assistant actually opened in this run:&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="err"&gt;missing:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;type:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'string'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;description:&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;'What&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;missing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;unclear&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;documentation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;one&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;two&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;short&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;sentences.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;It&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;rendered&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Markdown&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;documentation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;owners:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;'link&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;each&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Folio&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;page&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;you&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;actually&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;opened&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;this&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;that&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;related&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;(/s/&amp;lt;space&amp;gt;/p/&amp;lt;id&amp;gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;'...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Never&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;invent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;link&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;never&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;link&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;page&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;you&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;did&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;read&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;this&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;run.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5umktpzb1uca05ytqfbs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5umktpzb1uca05ytqfbs.png" alt="Questions without answers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;"Questions without an answer". The person's own words come first, the assistant's restated question under them, and then what was missing. This frame is from the recording made before the links fix.&lt;/p&gt;

&lt;p&gt;An instance administrator sees every conversation. A space administrator sees the same page limited to the spaces they administer. A personal access token is refused there. Opening a conversation is written to the audit log, and the conversation shows a "Who opened this conversation" block with the name and the time.&lt;/p&gt;

&lt;p&gt;The space admin writes the missing section, Jamie asks again in a new conversation, and the answer names the finance lead and links to "Refund policy".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpo6epv8k4suud3gfa8o8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpo6epv8k4suud3gfa8o8.png" alt="Edited rule"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That description is the second version. The first one only said what to put in missing, and in the 19 runs we recorded for video the model wrote plain text and linked a page once. So the recording above has no links in the column. We fixed it in the tool description, not in the UI, and a live check afterwards gave links in all 5 of 5 unanswered questions, each to a page the assistant had read in that run.  &lt;/p&gt;

&lt;h2&gt;
  
  
  The same pages for outside agents
&lt;/h2&gt;

&lt;p&gt;/mcp gives any MCP client 23 tools with a personal token or OAuth, including search and fetch for ChatGPT deep research. The client works with your rights and nothing more:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp add folio &lt;span class="nt"&gt;--transport&lt;/span&gt; http https://&amp;lt;host&amp;gt;/mcp &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer folio_pat_…"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two things do not carry over: outside agents do not see .agent, and only the built-in assistant records unanswered questions. For outside agents the package has agent-playbook.md, the same rules as an ordinary page.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does not do
&lt;/h2&gt;

&lt;p&gt;Folio AI needs a Cursor subscription, and the pages it works with go to Cursor. There is no other provider yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Want to take a look?
&lt;/h2&gt;

&lt;p&gt;Folio is open source (MIT): &lt;a href="https://github.com/evergreen-it-dev/folio" rel="noopener noreferrer"&gt;https://github.com/evergreen-it-dev/folio&lt;/a&gt;. The demo is at &lt;a href="https://demo.foliowiki.online" rel="noopener noreferrer"&gt;https://demo.foliowiki.online&lt;/a&gt; (pick Sam on the sign-in screen; data resets daily), and there is a short tour at &lt;a href="https://foliowiki.online" rel="noopener noreferrer"&gt;https://foliowiki.online&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;I'd be glad if it helps you. And I'm glad to talk about AI SDLC and how you can do the same in your own company.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>onboarding</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>I Gave AI Agents Actual Job Descriptions. My Team's Delivery Speed Went Up 300%. Here's the Setup</title>
      <dc:creator>Kravtsov</dc:creator>
      <pubDate>Tue, 07 Jul 2026 14:06:05 +0000</pubDate>
      <link>https://dev.to/sergii-kravtsov/i-gave-ai-agents-actual-job-descriptions-my-teams-delivery-speed-went-up-300-heres-the-setup-52jd</link>
      <guid>https://dev.to/sergii-kravtsov/i-gave-ai-agents-actual-job-descriptions-my-teams-delivery-speed-went-up-300-heres-the-setup-52jd</guid>
      <description>&lt;p&gt;Hey — I'm Sergii, I run &lt;a href="https://www.connectiveone.io/en" rel="noopener noreferrer"&gt;ConnectiveOne&lt;/a&gt; (an AI-powered comms platform) and co-founded &lt;a href="https://evergreen.team/" rel="noopener noreferrer"&gt;Evergreen&lt;/a&gt;, a dev shop out of Kyiv. I want to walk through, in actual technical detail, how we rebuilt our SDLC around AI agents — not the "we added Copilot" version of this story, the version where it took us over a year, we broke things, and we ended up with a setup that other engineers might actually find useful to steal from.&lt;/p&gt;

&lt;p&gt;TL;DR: giving a coding assistant unlimited scope and just chatting with it doesn't scale past a certain point. Giving it a narrow role, a written spec of its boundaries, and a quality gate before a human ever sees the diff — that scales. This post is the "how," with the actual structure we use.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem, concretely
&lt;/h2&gt;

&lt;p&gt;If you've used Claude Code or Cursor for more than a few weeks, you've probably hit this: you git clone, you start asking it things — "why is this erroring," "can you refactor this," "how do I wire this up" — and for the first few sessions it's magic. Then context starts leaking. It re-derives your architecture every session. It doesn't remember the convention you told it about three days ago. Token costs climb. And the output quality becomes a function of how well you phrased the prompt that particular morning, not a property of your codebase or your process.&lt;/p&gt;

&lt;p&gt;That's not a model problem. It's an architecture problem — you're running a chat, not a system.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we built instead: agents with job descriptions
&lt;/h2&gt;

&lt;p&gt;Here's the mental model shift that actually mattered: stop treating the agent like a chatbot you're negotiating with, and start treating it like a new hire you're onboarding. A new hire doesn't get "here's the whole codebase, go wild." They get a role, a scope, a set of docs to read, and boundaries on what they're allowed to touch.&lt;/p&gt;

&lt;p&gt;We formalize this as a rules layer that lives in the repo, versioned like everything else. If you're on Cursor this is literally .cursor/rules and .cursor/agents; if you're on Claude Code or something else, the mechanism differs but the principle doesn't: if a convention isn't written down somewhere the agent can read it, it doesn't exist as far as the agent is concerned. Don't rely on the model "just knowing" your team's patterns from the code alone.&lt;/p&gt;

&lt;p&gt;A simplified version of what one of our role files looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;backend-development-agent&lt;/span&gt;
&lt;span class="na"&gt;scope&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;services/orders/**&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;services/payments/** (read-only, no writes)&lt;/span&gt;
&lt;span class="na"&gt;forbidden&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;infra/**&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;CI/CD config&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;anything touching auth middleware&lt;/span&gt;
&lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;architecture spec (docs/specs/orders-service.md)&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;existing test suite&lt;/span&gt;
&lt;span class="na"&gt;outputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;implementation + updated unit tests&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;updated README section for the touched module&lt;/span&gt;
&lt;span class="na"&gt;must_pass_before_handoff&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;lint&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;full test suite (local)&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;self-review checklist (see docs/agent-checklist.md)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing exotic here. The value isn't in any single line — it's that this document exists at all, is checked into version control, and is the actual contract the agent operates under, instead of whatever context happened to survive to the end of a long chat session.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three pillars, in practice
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Rules as source of truth. Already covered above — the point is it's a versioned artifact, not tribal knowledge in a senior dev's head.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Role-based agents, not general-purpose ones. We run separate agents for backend, UI/UX, QA, architecture review, and documentation — each with its own scope file like the one above. This sounds like overhead until you compare it to the alternative: one assistant that touches everything, with quality that degrades the more creative latitude you give it. LLMs behave better with a tight job description than with "help me with anything," the same way a contractor does better with a scope of work than with "make the house nicer."&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AI transforms the SDLC, it doesn't replace it. Our actual pipeline: requirements → design → dev → test → deploy, with an agent (or agent pair) per phase and an explicit handoff artifact between phases — a markdown spec, not a copy-pasted Slack message. If your team's process for sharing a good prompt is "I pasted it in our dev channel," that's not a system, that's folklore, and it doesn't survive the person who wrote the prompt going on vacation.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The rollout order that actually worked (and the one that didn't)
&lt;/h2&gt;

&lt;p&gt;We tried going straight to "multiple agents running in parallel across the codebase" early on. It went about how you'd expect: fast, confident-sounding output, and a nontrivial chunk of it subtly wrong in ways that were expensive to catch after the fact.&lt;/p&gt;

&lt;p&gt;What worked instead — and what I'd tell any team starting this today:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pick one narrow, boring process. PR review, doc generation, one specific QA pass. Not "the whole SDLC." One thing.&lt;/li&gt;
&lt;li&gt;Build one role-scoped agent for it. Validate on real tickets, not toy examples, before it touches anything else.&lt;/li&gt;
&lt;li&gt;Add roles one at a time. Each new agent gets its own scope file, gets proven on real work, then becomes permanent.&lt;/li&gt;
&lt;li&gt;Only once gates are stable, add parallelism. Multiple agents running concurrently and handing off context to each other — what we internally call an agent swarm — only makes sense once you already have stable rules and an automated quality gate in front of merge. Skipping to this step is the single most common mistake I see teams make.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Where the human actually sits
&lt;/h2&gt;

&lt;p&gt;This is the part people get anxious about, so let me be specific instead of hand-wavy.&lt;/p&gt;

&lt;p&gt;We run automated review (CodeRabbit, in our case) as a first-pass filter — style, obvious issues, convention violations, basic security smells. That's it. That's what it catches. It does not catch intent drift — an agent producing code that's clean, passes tests, lints fine, and still solves a subtly different problem than what was actually asked, because context drifted over a long session or an upstream agent handed off a stale spec. That class of failure needs a human, every time, no exceptions. Architecture decisions and business-logic correctness stay human. Final merge sign-off stays human.&lt;/p&gt;

&lt;p&gt;What changes isn't whether a human is in the loop — it's what the human is actually reviewing. Less "does this line of code look right," more "does this diff match the intent, and did the agent stay inside its scope file." That's a different skill than traditional code review, and it's worth explicitly training your team on it rather than assuming it transfers automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  The tooling gap nobody tells you about: provenance
&lt;/h2&gt;

&lt;p&gt;Here's the thing that bit us hardest and that I don't see written about much: when an agent-generated change causes a problem three weeks later, "why did it do this" is not something you can just ask the engineer who reviewed the PR, because they reviewed a diff, not a decision process. And re-running the same agent against old context and hoping it explains itself consistently is not a reliable debugging method.&lt;/p&gt;

&lt;p&gt;We ended up building an internal orchestration layer (we call it C1Cursor) specifically to solve this — every agent-generated diff gets tagged at execution time with: which agent, which role/scope, what context it actually had access to (which docs, which code, which upstream agent's output), and which gates it passed or failed. This turns "why did this happen" from an archaeology project into a lookup. If you're rolling this out yourself and don't have budget for custom tooling, at minimum log this metadata somewhere queryable — even a structured commit message convention is better than nothing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The number, and why I wouldn't lead with it
&lt;/h2&gt;

&lt;p&gt;Doing all of this got ConnectiveOne to roughly +300% development velocity year over year, against our own prior baseline. I mention it because people ask, but I wouldn't lead a technical conversation with it, because velocity without the gating and provenance layer above is exactly how teams end up shipping fast and debugging blind. The metric that actually told us this was sustainable wasn't velocity — it was our quality-gate pass rate holding steady as we added more agents and more parallelism. Velocity was downstream of that staying true, not a separate win to brag about.&lt;/p&gt;

&lt;h2&gt;
  
  
  If you're starting this next week
&lt;/h2&gt;

&lt;p&gt;Don't start by picking a model. That's the wrong first decision. Start by writing down, in a file your agent can actually read, what one narrow process is allowed to touch and what it isn't. Prove that one thing works on real tickets. Then add the next role. Resist the urge to parallelize before your gates are boring and reliable — boring is the goal, not a consolation prize.&lt;/p&gt;

&lt;p&gt;Happy to go deeper on any piece of this in the comments — the role-file format, the provenance tooling, or the QA agent setup specifically. This is still an evolving system for us, and I'd rather compare notes with people building the same thing than pretend we have it fully solved.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>automation</category>
      <category>aiops</category>
    </item>
  </channel>
</rss>
