Read in:
Русский

Один автор на базу

Коротко. trip2g публикует Obsidian-хранилища как сайты и отдаёт их AI-агентам по MCP. Этот текст про то, как использовать его как альтернативу Confluence без матрицы прав. У каждой базы знаний здесь один автор: её владелец, человек или его агент. Все остальные читают. Пространство команды — это несколько таких баз со своими хозяевами и один эндпоинт, который ищет по всем сразу; это и называется федерацией. Тогда большая часть того, что приходится настраивать в правах доступа Notion или Confluence, отпадает. Кто может править заметку, видно из того, чья это база. Нашли ошибку в чужой заметке — пишете владельцу, а не правите его базу. Это модель «один пишет, остальные читают» для распределённой базы знаний. У неё есть предшественник, который не взлетел, и у неё есть настоящая цена. Про то и другое ниже.

Как гниёт общая вики

Каждая командная вики, в которой я работал, начиналась одинаково. Одно пространство, править могут все, про доступ никто не думает. Потом приходит подрядчик, и страницу с зарплатами надо спрятать. Потом клиенту дают гостевой доступ. Потом одна подстраница должна быть строже родительской.

Инструменты всё это позволяют, в этом и беда. В Notion подстраница наследует права родителя, а внутри неё их можно переопределить. Уровней доступа шесть, от Full access до Can view, два из них только для баз данных, плюс гости извне воркспейса. Каждое переопределение кто-то однажды сделал, и никто уже не помнит, что оно было.

Чем это кончается, Atlassian меряет сама. На её странице поддержки Confluence spaces with too many permissions стоит ограничитель в 20 000 прав на одно пространство. Считается «каждое отдельное право, выданное пользователю или группе», и выше порога тормозят дерево страниц, просмотр и редактирование. Двадцать тысяч прав в одном пространстве никто не проектирует: они копятся по одной разумной просьбе за раз.

Показательны и советы, которые идут в комплекте. Atlassian предлагает выдавать права группам, а не людям, заводить новые пространства поменьше под команды и проекты, назначать владельцев и регулярно чистить устаревшее. Каролина Вебер из Honicon в статье Sustainable permission models for Confluence описывает, что бывает до чистки: «запутанный клубок прав: слишком много администраторов, неясная ответственность», и «никто толком не знает, у кого к чему есть доступ». Её рецепт: несколько понятных групп и отдельные пространства вместо ограничений на уровне страниц.

Параллельно гниёт содержимое. Гайд Rencore по разрастанию Confluence по сути список детекторов: страницы без правок 365 дней, пространства без активности 365 дней, страницы-сироты без родителя, пустые пространства, метки на одной странице. Всё это принадлежит всем, а значит никому.

Если сложить эти рецепты, они указывают в одну сторону: пространства поменьше, у каждого владелец, люди сгруппированы по тому, что им можно. Это шаг к «одна база, один хозяин». Инструменты останавливаются на полпути, потому что общая куча и есть их продукт.

Правило и что оно убирает

Я прошёл этот путь до конца. У базы один автор. В trip2g это значит один vault: заметки попадают на сервер из Obsidian владельца, через git push, через редактор в браузере или от агента с API-ключом владельца. Читатели читают, а отправить обратно могут разве что ответ в форму, если владелец поставил её в заметку. Токен подписчика наследует ровно то, что подписчику можно читать, а MCP-инструменты, доступные читателю (search, note_html, expand, similar), только читают.

Пространство команды при этом собирают из частей. У платформенной команды своя база. У HR своя. У партнёра своя, на его сервере. Мой хаб подключает каждую через KB-заметку: обычную заметку, во фронтматтере которой адрес пира, а в тексте написано, когда в эту базу идти. Агент спрашивает один эндпоинт, хаб разносит вопрос по базам (как устроена федерация).

Теперь посмотрите, что осталось настраивать. Колонки «редактирование» в матрице больше нет: автор у базы один, выдавать право правки некому. Остаётся чтение, и нарезано оно нарочно крупно. Владелец группирует заметки в подграфы и выдаёт ключу каждого пира набор подграфов. Новый ключ не видит ничего. Отзыв занимает одну кнопку, и следующий запрос пира получает 401.

Между базами стена — не настройка, которую можно впопыхах выставить не так. Все федеративные инструменты читают: federated_search, federated_note_html, federated_expand, federated_similar, federated_instructions. Даже GraphQL-проброс к пиру проверяет запрос и отклоняет всё, что не чтение. Записать в мою базу из вашей нельзя, потому что такого вызова просто нет. На вопрос «кто может править ранбук платформенной команды?» один ответ, и для него не нужно открывать страницу настроек.

На вопрос «кто отвечает за эту страницу?» тоже появляется ответ. Страница лежит в чьей-то базе, этот кто-то и отвечает. Если он уходит, его база устаревает целиком и заметно, а не оставляет пятьсот сирот по общему пространству.

Исправление — это сообщение

Здесь обычно возражают: а если я вижу ошибку в вашей заметке?

Тогда вы пишете мне. Вы не правите мою заметку. В общей вики быстрая правка мимоходом — лучшее, что там есть: увидел неправильный порт, поменял, готово. Я отказываюсь от этого сознательно и хочу прямо сказать, что это потеря. Опечатка теперь стоит сообщения и ожидания.

Зато моя база говорит только то, что сказал я. Когда агент цитирует ранбук платформы, это предложение написал владелец ранбука. Никто не вписал правку, пока хозяин был в отпуске. Почему для агентов это важно, я измерял в ru/thoughts/federation-supply-chain: модель, ищущая по слитой куче, находит нужный материал и приписывает его не тому автору. Когда у базы один автор, ответ не теряет его имя.

Как именно ходит это сообщение, пока не решено. Сегодня это любой канал, которым вы и так общаетесь с владельцем. Ближайшее, что есть в платформе, — форма в заметке, которая сохраняет ответы при этой заметке. Процессом ревью я бы это не назвал. А если вы с моей заметкой не согласны, а не поправляете её, правильнее написать свою заметку в своей базе и сослаться на мою. Тогда существуют обе точки зрения, каждая под именем автора.

Это уже пробовали в 2011-м

Идея не моя. Уорд Каннингем, который придумал вики, показал Federated Wiki на IndieWebCamp в 2011 году. У каждого свой вики-сайт. Чужую страницу править нельзя: её форкают к себе и меняют свою копию. Джон Уделл писал об этом в InfoWorld в 2015-м: «если я внесу изменения, вы можете влить их к себе, а можете и не вливать». Обычная вики, по словам Майка Колфилда, которого цитирует Уделл, — «безжалостная машина консенсуса». Каннингем называл альтернативу «хором голосов».

В массы это не пошло, и причины стоит прочитать, прежде чем повторять идею. Нужен был свой сервер. Пользоваться было трудно: один пользователь в 2018-м написал, что у него оно «просто не заработало», а fedwiki.org назвал «очень клёвым, но трудным в использовании». И поиск между сайтами был слабым. Он шёл по текущему «соседству», то есть по сайтам, на которые вы успели наткнуться, и, как объяснял Уделл, «видит только заголовки и первые абзацы страниц вашего соседства». Слияние тоже было ручным: форк оставался отдельной копией, пока исходный хозяин сам не решал забрать изменения.

Вот что trip2g делает по каждому пункту иначе, а где так же.

Поиск чужих баз. Список пиров здесь не сессия браузера, а набор KB-заметок в вашем vault, поэтому он не пропадает, и у каждой есть описание для читателя: «Use when: … Don't use when: …». Агент видит это описание в выдаче и решает, идти ли туда. federated_search запускает собственный поиск каждого пира по всем его заметкам, а не по списку заголовков, а без kb_id разносит запрос по всем доступным пирам. federated_instructions отдаёт агенту указания самого пира до того, как он начнёт искать. Во времена Каннингема читателем был человек, который кликал между сайтами. Теперь это часто агент через MCP, а агенту не лень прочитать двадцать описаний и сделать пять запросов.

Слияние. Форков в trip2g нет вовсе. Вы читаете мою базу на месте, и всё, что вы выносите, сохраняет имя моей базы. Механику копирования и слияния я не решил, а выбросил. Цена — тот самый хор: в Federated Wiki десять слегка разных версий страницы жили рядом. Здесь у каждого владельца одна версия, а ваша заметка ссылается на мою.

Свой сервер. По-прежнему нужен. Ваша база — это инстанс, который держите вы или тот, кому вы доверяете. В этом и смысл затеи, и ровно об это споткнулась Federated Wiki.

Где это слабее, чем звучит

Внутри одного инстанса правило — договорённость, а не стена. API-ключ даёт доступ уровня администратора ко всему инстансу. Можно синхронизировать три репозитория в один инстанс через --meta subgraph=… (документация), и ничто не мешает двум людям делить один ключ. Единственного автора гарантирует только топология между инстансами, где пир умеет лишь читать. Хотите гарантию — дайте каждому владельцу свой инстанс. Хватает одного — значит, у вас общая вики с хорошими манерами.

Бывает и по-настоящему совместная работа. Спецификация, которую двое пишут за один день, протоколы встреч, журнал решений проекта без единого хозяина. В этой модели такой документ лежит в чьей-то базе, а второй присылает замечания. Это медленнее совместного редактирования, и для таких документов общий редактор подходит лучше.

И масштаб. Я гоняю это на своих базах и на небольшом публичном хабе, который федерирует ещё несколько. Как привычка «пиши владельцу» переживёт компанию на пятьсот человек, я не видел и сказать не могу. Подозреваю, что это дешевле аудита прав. Но это подозрение.

Ещё одна цена описана в мембране: отказ федерации выглядит одинаково, нет ли базы вовсе или вас в неё не пустили. Снаружи вы видите меньше, чем в общей вики, и это задумано.

Итого: вы теряете быструю правку мимоходом и общий черновик. Получаете базы, каждая из которых говорит ровно то, что сказал её хозяин, права, которые читаются одной строкой, и ответ на «кто за это отвечает?», который не надо выяснять по коридорам. ru/thoughts/data-mesh-for-knowledge смотрит на тот же ход со стороны инженерии данных, где у него есть имя и несколько лет критики.