"text":"МЕХАНИЗМ ПАМЯТИ dsh-memory v2\n\nСлои. Protocol (track agent, importance always) инжектится в первый ход. Session (directive scope workspace) инжектится в первый ход текущего чата. Reference (called) и Archive (state archive) только по запросу.\n\nЧто инжектится всегда: все track agent + importance always, плюс directive_ scope workspace state active для текущего chatId с проверкой workspaceKey. Fingerprint: если тот же набор уже в истории чата — пропуск всего блока.\n\nЗапросы через dsh_memory (op):\nlist track scope importance state since limit — items с preview и bytes, totalBytes, matched\nget ids — items с content, totalBytes\nrecent since — items\nunread chatId — новее lastInjectAt\nsearch query track — plain substring, totalBytes\ndirectives chatId state active|done|archive|all — директивы\nbudgets — used по track и scope, alwaysCount, лимиты\nadd entry — новая запись, entry включает track scope workspaceKey key text importance tags\nreplace id text tags importance state chatId — правка\nremove id — удаление\n\nСервер ВСЕГДА отдаёт totalBytes в meta ДО контента. Модель видит объём и решает: взять всё, взять по ids, взять preview, отложить.\n\nТаксономия ключей: user_ факты о пользователе, project_ проекты, directive_ правила и шаги, pref_ привычки, tech_ стек, interest_ интересы, pitfall_ грабли и обходы, decision_ архитектурные решения. Префикс задаёт группу, программа не решает релевантность.\n\nЛимиты: always записей 10, tags 5 на запись по 32 символа, директив на чат 5, preview 200. Калибровать по обратной связи.\n\nОбновление факта: replace по тому же id, не дубликат. AUTHENTIC EXTRACTION ONLY: только явно сказанное пользователем. NEVER cite memory tags в ответе.",
"text":"МЕХАНИЗМ ПАМЯТИ dsh-memory v2\n\nСлои. Protocol (track agent, importance always) инжектится в первый ход. Session (directive scope workspace) инжектится в первый ход текущего чата. Reference (called) и Archive (state archive) только по запросу.\n\nЧто инжектится всегда: все track agent + importance always, плюс directive_ scope workspace state active для текущего chatId с проверкой workspaceKey. Fingerprint: если тот же набор уже в истории чата — пропуск всего блока.\n\nЗапросы через dsh_memory (op):\nlist track scope importance state since limit — items с preview и bytes, totalBytes, matched\nget ids — items с content, totalBytes\nrecent since — items\nunread chatId — новее lastInjectAt\nsearch query track — plain substring, totalBytes\ndirectives chatId state active|done|archive|all — директивы\nbudgets — used по track и scope, alwaysCount, лимиты\nadd entry — новая запись, entry включает track scope workspaceKey key text importance tags\nreplace id text tags importance state chatId — правка\nremove id — удаление\n\nСервер ВСЕГДА отдаёт totalBytes в meta ДО контента. Модель видит объём и решает: взять всё, взять по ids, взять preview, отложить.\n\nТаксономия ключей: user_ факты о пользователе, project_ проекты, directive_ правила и шаги, pref_ привычки, tech_ стек, interest_ интересы, pitfall_ грабли и обходы, decision_ архитектурные решения. Префикс задаёт группу, программа не решает релевантность.\n\nКОГДА ПИСАТЬ (триггеры, важнее чем формат):\n1. Завершён этап работы (коммит, фича, интеграция) -> project_<тема> или decision_<тема>, importance called. Что сделано, где код, какие грабли.\n2. Наступил на грабли второй раз -> pitfall_<тема>, called. Симптом + обход.\n3. Изменилось правило поведения (новая политика, новый лимит) -> replace существующего protocol_*, всегда. Не дубликат.\n4. Появился новый инструмент/команда/приложение -> protocol_*, always. Чтобы модель в новом чате знала.\n5. Пользователь сказал факт о себе или предпочтение -> user_/pref_, called.\n6. Проект/сервис добавлен или изменён -> project_*, called.\n\nПравило записи: после каждого завершённого этапа (2+ коммита или значимая правка) — записать хотя бы одну project_ или decision_ запись. Если этап был без грабель и без новых правил — всё равно project_: что сделано, где смотреть. Иначе через неделю память не отражает реальность.\n\nЛимиты: always записей 10, tags 5 на запись по 32 символа, директив на чат 5, preview 200. Калибровать по обратной связи.\n\nОбновление факта: replace по тому же id, не дубликат. AUTHENTIC EXTRACTION ONLY: только явно сказанное пользователем. NEVER cite memory tags в ответе.",
"importance":"always",
"importance":"always",
"tags":[
"tags":[
"protocol",
"protocol",
"memory"
"memory",
"triggers"
],
],
"version":4,
"version":5,
"createdAt":"2026-11-02T23:35:16.258Z",
"createdAt":"2026-11-02T23:35:16.258Z",
"updatedAt":"2026-11-03T03:41:45.792Z",
"updatedAt":"2026-11-07T05:57:12.533Z",
"lastRecalled":null,
"lastRecalled":null,
"recallCount":0,
"recallCount":0,
"bytes":2327
"bytes":3807
},
},
{
{
"id":"2853ce0e-de50-455c-bd5a-ebbf9a3fe337",
"id":"2853ce0e-de50-455c-bd5a-ebbf9a3fe337",
@ -155,7 +156,120 @@
"lastRecalled":null,
"lastRecalled":null,
"recallCount":0,
"recallCount":0,
"bytes":2117
"bytes":2117
},
{
"id":"3e51562d-a56b-4919-9720-cf36597553b6",
"track":"agent",
"scope":"user-global",
"workspaceKey":"",
"key":"project_mcp_integration",
"text":"MCP-интеграция ArtCraft в dsh-memory. Сделано 06.11.2026, коммиты 45222a0, 93504ed, fe9c4eb, f03dd76, 45ace2c, 4090ba0.\n\nЧТО СДЕЛАНО. Мост научился управлять приложениями ArtCraft через MCP (stdio JSON-RPC). 17 приложений: vectorcraft, photocraft, figcraft, designcraft, deckcraft, cadcraft, craftanything, effectcraft, filmcraft, gridcraft, lightcraft, materialcraft, pdfcraft, solidcraft, soundcraft, texturecraft, wordcraft. Порты 7979-7995, у каждого свой. Клиент поднимается лениво при первом вызове. Инструменты <app>_mcp_tools и <app>_mcp_call.\n\nФАЙЛЫ. bridge/mcp-client.js (JSON-RPC по stdio), bridge/mcp-registry.js (discovery, порты, флаги коннекта), bridge/mcp-tools.js (менеджер, ленивый старт, launchGui, stop), bridge/server.js (маршруты /mcp/apps, /mcp/launch, /mcp/stop, /mcp/rescan, /mcp/root).\n\nLIVE РЕЖИМ. vectorcraft.exe --control 7979, CLI коннектится через --connect 127.0.0.1:7979. Флаги у приложений разные: --connect ADDR (vectorcraft, designcraft, gridcraft, wordcraft, cadcraft, solidcraft, soundcraft, deckcraft), --bridge (photocraft, effectcraft, filmcraft, materialcraft, texturecraft), --attach (figcraft). pdfcraft и craftanything live не умеют.\n\nГРАБЛИ. Мост кэширует CLI-клиент: если окно подняли после старта клиента, он не переподключится. launchGui это лечит (закрывает старый клиент). Мост выбрасывает inline-картинки из MCP-ответов (mcp-client.js:81) — всегда просить path. ui_screenshot не принимает path, файл пишет screenshot {window:true, path}. draw_shape поле shape не kind, add_text color не fill — схемы через _mcp_tools {filter}.",
"importance":"called",
"tags":[
"project",
"mcp",
"artcraft"
],
"state":null,
"chatId":"",
"version":1,
"createdAt":"2026-11-07T05:57:38.065Z",
"updatedAt":"2026-11-07T05:57:38.065Z",
"lastRecalled":null,
"recallCount":0,
"bytes":2024
},
{
"id":"4bcc17ab-cc89-4877-8695-63042b0aeaab",
"track":"agent",
"scope":"user-global",
"workspaceKey":"",
"key":"decision_bash_policy",
"text":"Bash-политика dsh-memory: safe-list вместо блоков. Решение принято 07.11.2026, коммиты c2cf419, 69602ec, a298e6d.\n\nПОЧЕМУ. Раньше метасимволы (| & > < ; обратный апостроф $) и blacklist-паттерны блокировали команду намертво. Это создавало видимость защиты: обход через node script.mjs был тривиален, не логировался, а модель обходила блоки через .mjs-файлы. Пользователь сформулировал: программа не должна запрещать, она должна спрашивать.\n\nКАК СЕЙЧАС. Жёстко блокируются только пустая команда и >2000 символов. Safe-list (без подтверждения): pwd, dir, ls, tree, where, which, whoami, hostname, uname, ver, cd, echo, date, time, git status/diff/log/show/branch/rev-parse/ls-files/describe/remote/config (с пропуском -C, -c, --no-pager), npm/pnpm/yarn/bun test/run/build/lint/typecheck/check/ls/list/why/outdated/info/view (с пропуском --prefix, --workspace, -w), npx tsc/eslint/prettier/vitest/jest/mocha, node/npm/npx --version, tsc, eslint. Не включены сознательно: cat, head, tail, type, more, less — читают файлы в обход validatePath.\n\nPOLICY-ФЛАГИ (confirm): shell (метасимволы), multiline, destructive (rm, del, format, mv, cp, git push/commit/reset/clean, taskkill, reg, sc, schtasks), network (curl, wget, ssh, scp, ftp, powershell, iwr), absolute-path, parent-path. Любой флаг отменяет allow.\n\nДВА СЛОЯ. Pre-flight: модель объявляет в тексте до отправки, ждёт да (protocol_policy). Панельный confirm: Allow/Deny с ожиданием клика (content.js executeOne), fail-closed при недоступной панели (E_CONFIRM_UNAVAILABLE).\n\nГРАБЛИ. git -C path status раньше уходил в confirm (skipGlobalFlags лечит). Двойной E_NEEDS_CONFIRM в логе (server.js: при confirmToken сразу call(true)).",
"importance":"called",
"tags":[
"decision",
"bash",
"policy",
"security"
],
"state":null,
"chatId":"",
"version":1,
"createdAt":"2026-11-07T05:57:41.076Z",
"updatedAt":"2026-11-07T05:57:41.076Z",
"lastRecalled":null,
"recallCount":0,
"bytes":2252
},
{
"id":"917a3647-9bb5-4283-8eff-f59dfa1c3648",
"track":"agent",
"scope":"user-global",
"workspaceKey":"",
"key":"pitfall_eol_normalize",
"text":"dsh_edit не находит oldText в файлах со смешанными CRLF/LF. Наступал многократно за 06-07.11.2026 на server.js, tools.js, panel.js, overlay.css, background.js.\n\nСИМПТОМ. E_ARGS_INVALID oldText not found (0 matches), хотя текст визуально совпадает. Причина: файл в CRLF, а oldText в LF (или наоборот).\n\nОБХОД. Перед правкой проверить EOL скриптом (посчитать CRLF vs LF), нормализовать файл к LF: fs.readFileSync -> replace(CRLF, LF) -> writeFileSync. Потом dsh_edit. После правки node -c для проверки синтаксиса. Для больших блоков (десятки строк) надёжнее не dsh_edit, а отдельный скрипт замены по маркерам: найти индексы start/end, собрать merged = before + section + after.",
"importance":"called",
"tags":[
"pitfall",
"eol",
"crlf",
"dsh_edit"
],
"state":null,
"chatId":"",
"version":1,
"createdAt":"2026-11-07T05:57:44.088Z",
"updatedAt":"2026-11-07T05:57:44.088Z",
"lastRecalled":null,
"recallCount":0,
"bytes":972
},
{
"id":"1c3a7d4c-fef0-4575-ab7c-d6cf1978e9d0",
"track":"agent",
"scope":"user-global",
"workspaceKey":"",
"key":"pitfall_dsh_edit_large_oldtext",
"text":"dsh_edit с очень большим oldText (десятки строк) может применить замену криво: вставить новый блок, но не удалить старый, или задвоить содержимое. Произошло 07.11.2026 с README.md: файл раздулся с 690 до 1396 строк (дубли всех разделов).\n\nПРИЧИНА. Не подтверждена достоверно, но воспроизводилось.\n\nОБХОД. Для блоков больше 15-20 строк не использовать dsh_edit. Писать новый блок в отдельный .md/.txt файл, затем скрипт: прочитать целевой файл, найти indexOf(startMark) и indexOf(endMark), собрать merged = lines.slice(0,start) + sectionLines + lines.slice(end), записать. Это детерминированно. После — проверить размер (bytes, lines) и посчитать вхождения ключевых заголовков (должно быть по 1). При сомнениях git checkout -- file и повторить.",
"importance":"called",
"tags":[
"pitfall",
"dsh_edit",
"large-block"
],
"state":null,
"chatId":"",
"version":1,
"createdAt":"2026-11-07T05:57:47.096Z",
"updatedAt":"2026-11-07T05:57:47.096Z",
"lastRecalled":null,
"recallCount":0,
"bytes":1176
},
{
"id":"06442ed5-f07c-4beb-bbaf-6084b5b2dddc",
"track":"agent",
"scope":"workspace",
"workspaceKey":"V:/Site",
"key":"project_warp_cz",
"text":"WARP на чешском VPS (cvetochny, 85.137.166.251): скрыть IP VPS от клиентов российского туннеля. Спроектировано 06.11.2026, скрипты написаны, на сервер не выкатывалось.\n\nЗАЧЕМ. Клиенты site-to-site туннеля Россия-Чехия (RU 188.127.239.17, CZ 85.137.166.251) выходят в интернет с чешского IP. WARP завернёт только клиентов (10.8.1.0/24) в Cloudflare, сервисы на самом VPS (3proxy :3128 для Telegram-бота starvery, nginx :8443) останутся на чешском IP.\n\nФАЙЛЫ. backup-20261104/warp-cz/: warp-on.sh (wg-quick up wgcf, таблица warp id 201, правило from 10.8.1.0/24 priority 50, NAT на wgcf, TCPMSS clamp, проверка trace), warp-off.sh, warp-status.sh, wgcf.conf.example, README.md. Раздел 18 в backup-20261104/RECOVERY-AWG-SITE-TO-SITE.md.\n\nРЕЖИМ. Fail-open: старый NAT -s 10.8.1.0/24 -o ens3 MASQUERADE не удаляется. При падении WARP клиенты получают чешский IP, не теряют связь. Геолокация не важна.\n\nГРАБЛИ. Table = off в wgcf.conf обязателен (иначе wg-quick перезапишет default route, SSH умрёт). DNS = закомментировать (иначе /etc/resolv.conf перепишется, 3proxy/nginx/apt начнут резолвить через 1.1.1.1). WARP-адреса общие, Google/банки дают капчу. Геолокация не привязана к Чехии (Cloudflare выходит через ближайший DC). Хостинг может блокировать WARP — проверять curl --interface wgcf https://www.cloudflare.com/cdn-cgi/trace до включения.",