[2026-05-15] obsidian-vault-strategy: remove hardcoded files, add 12 enrichment use cases

This commit is contained in:
Alexey Martemyanov
2026-05-15 20:45:57 +06:00
parent c4bee9e5ad
commit b17da7efff
3 changed files with 80 additions and 124 deletions
+1
View File
@@ -1,4 +1,5 @@
- [ ] objc.io Advanced Swift (in Downloads) videos -> watch; upload to truenas/edu ()
- [ ] Hermes memories -> obsidian, purge
- [ ] Смеситель
- [ ] Клининг
@@ -221,70 +221,31 @@ Results → wiki/inbox → review
### Проект 4: Cross-domain Enrichment Agent
**Цель:** агент берёт личные списки, читает user profile, обогащает данными из внешних источников.
**Цель:** универсальный агент который берёт любой список/заметку из vault, читает user profile, обогащает данными из внешних источников.
**Первые три target notes:**
**Принципы (без хардкода конкретных файлов):**
**Target A: `personal/documents/app-ideas.md`**
```
Триггер: добавлена новая идея (git change detection) или еженедельно
Процесс:
1. Читает каждую идею без тега "analyzed"
2. YC search (corralm/yc-scraper или web search "site:ycombinator.com [keyword]")
3. ProductHunt search по ключевым словам
4. Web search конкурентов
5. Сохраняет: personal/projects/app-analysis/[slug].md
- Existing solutions (кто, когда, funding)
- Differentiation opportunities
- Market gaps
- Verdict: "ниша занята / частично / свободна"
6. Добавляет тег "analyzed" + ссылку на анализ в app-ideas.md
```
1. **Target Discovery** — агент сам находит заметки которые поддаются обогащению: списки без внешних данных, заметки с тегом `enrich-me`, файлы давно не обновлявшиеся
2. **Profile-aware** — всегда читает `wiki/user-profile.md` перед обогащением, фильтрует под конкретный контекст
3. **Output isolation** — результат сохраняется как отдельная заметка рядом с исходной, исходник не трогает
4. **Source tagging** — каждый enriched факт содержит источник + дату → можно обновлять
**Target B: `family/documents/kids-activities.md` + `family/documents/games-wishlist.md`**
```
Триггер: еженедельно или при изменении файлов
Процесс:
1. Читает kids-activities + games-wishlist
2. Читает user-profile.md (возраст ребёнка, интересы, темперамент)
3. Cross-links: добавляет wikilinks между файлами
4. Фильтрует games-wishlist: "подходит для совместной игры с [возраст]"
5. External search: "co-op games dad and [age] year old", "best games for [interest]"
6. Сохраняет: family/projects/kid-games-together.md
- Текущие игры из списка (отфильтрованные, с объяснением)
- Новые рекомендации с обоснованием по профилю
- Разбивка по типу (кооп / соревновательные / обучающие)
```
**Target C: `family/documents/movies-watchlist.md`**
```
Триггер: еженедельно
Процесс:
1. Читает watchlist, находит фильмы без рейтинга/жанра
2. OMDB API / web search → добавляет жанр, год, рейтинг
3. Строит "похожие фильмы" список по просмотренным
4. Обновляет frontmatter watchlist
```
**User Profile** (создать `wiki/user-profile.md`):
**User Profile** (создать `wiki/user-profile.md`) — единый источник правды о пользователе:
```markdown
## Alex
- Интересы: home automation, Swift/iOS, AI agents, cycling, music production
- Текущие проекты: personal-os, executor, media-toolbox
## Ребёнок
- Возраст: [заполнить]
- Интересы: [заполнить]
- Игровой стиль: [заполнить]
- Что работает хорошо: [заполнить]
- Текущие проекты: [заполнить]
- Домены: [заполнить]
## Семья
- [заполнить]
- [заполнить — состав, возрасты, интересы]
```
**Примеры цепочек:** см. Часть 5a
**Стек:** Hermes cron + web toolset + terminal (git change detection) + obsidian MCP
**Оценка:** 1-2 недели на первые три target notes
**Оценка:** зависит от количества target notes; архитектура универсальная
---
@@ -353,88 +314,68 @@ Results → wiki/inbox → review
---
## Часть 5a — Расширенные use cases (твои примеры)
## Часть 5a — Паттерн: Personal Context → External Signal → Insight
Это отдельный класс задач — **cross-domain enrichment с внешними данными**. Не просто накопление знаний, а агент который берёт твои личные данные и обогащает их внешним контекстом.
Это отдельный класс задач — **cross-domain enrichment с внешними данными**. Агент читает личные данные из vault, учитывает профиль пользователя, обогащает внешними сигналами и возвращает персонализированный результат.
### Use case 1: Идеи приложений → конкурентный анализ
**Ключевое отличие от Google:** контекст про тебя уже внутри — агент не ищет абстрактный ответ, а фильтрует под конкретного человека.
### Общий паттерн
```
family/documents/app-ideas.md (список идей)
↓ агент читает каждую идею
↓ ищет по YC directory (5800+ компаний, есть scraper API)
↓ ищет по AngelList / Crunchbase / ProductHunt
↓ ищет по ключевым словам в web
↓ генерирует competitive landscape
↓ сохраняет в personal/projects/app-analysis/[idea-slug].md
```
**Что войдёт в анализ:**
- Существующие решения (кто, когда основан, funding)
- Дифференциаторы (что делают иначе)
- Незакрытые ниши
- Инсайты: "похожих YC компаний нет в этой вертикали"
**Источники данных:**
- YC: `https://www.ycombinator.com/companies` — scraper доступен (corralm/yc-scraper, Browse AI)
- ProductHunt: API есть
- Google/web search по ключевым словам идеи
---
### Use case 2: Активности с ребёнком × игры × психологический профиль
Это самый сложный и ценный use case — **multi-source cross-reference с профилем**.
```
family/documents/kids-activities.md ← "игры с ребёнком"
family/documents/games-wishlist.md ← список игр
wiki/user-profile.md ← профиль Alex + ребёнок (возраст, интересы, что работает)
Enrichment Agent
1. Cross-link: kids-activities → games-wishlist (wikilinks + Dataview)
2. Filter games: возраст ребёнка + совместная игра + интересы
3. External search: "co-op games for dad and [age] year old"
4. Психологический профиль (если есть заметки) → учитывает стиль обучения, темперамент
5. → family/projects/kid-games-together.md
- Список из текущих игр (отфильтрованный)
- Новые рекомендации из внешних источников
- Почему каждая игра подходит (по профилю)
```
**Ключевой паттерн:** агент не просто ищет — он **читает профиль и фильтрует под конкретного человека**. Это и есть разница с обычным Google поиском.
---
### Общий паттерн: Personal Context → External Signal → Insight
```
Личные данные в vault
+ User Profile (возраст ребёнка, интересы, предпочтения)
+ External APIs (YC, ProductHunt, Steam, RAWG, IMDB...)
Заметка/список в vault
+ Связанные заметки (через wikilinks / поиск)
+ User Profile (возраст, интересы, текущий стек, предпочтения)
+ External signal (web, API, RSS, marketplace)
Enrichment Agent (по триггеру или расписанию)
Enriched note в vault (cross-links + внешние данные + insights)
Enriched note в vault (insights + cross-links + источники)
```
**Другие возможные use cases по этому паттерну:**
- `movies-watchlist.md` → рекомендации похожих фильмов по жанрам + IMDB рейтинг → enriched watchlist
- `books-reading-list.md` → Goodreads/OpenLibrary → что похожего, порядок чтения, тематические связи
- `places-to-visit.md` → OpenStreetMap/маршруты → "эти места рядом, оптимальный маршрут"
- `home-automation-wishlist.md` → Home Assistant community → что уже реализовано, как интегрировать с нашим стеком
- Профиль инвестора/карьеры → Job boards / LinkedIn signals
### Иллюстративные примеры (не задачи, а цепочки мышления)
---
**1. Список идей приложений → конкурентный анализ**
Читает каждую идею → ищет по YC directory / ProductHunt / web по ключевым словам → кто уже делает, funding, незакрытые ниши → сохраняет анализ рядом с идеей
**2. Активности с ребёнком × список игр × профиль ребёнка**
Читает списки активностей + игр → читает профиль (возраст, интересы, темперамент, что работает) → cross-links между файлами → фильтрует игры под совместную игру → ищет новые по интересам → персонализированные рекомендации с обоснованием
**3. Список для чтения → learning path**
Книги/статьи + текущие знания из wiki → определяет prerequisites, оптимальный порядок, находит пробелы в теме
**4. Wishlist путешествий → план поездок**
Список мест + сезонность + текущие проекты (когда реально есть время) → какие места удобно совмещать, оптимизированный план на год
**5. Профили контактов → напоминания о связи**
Список людей с датой последнего общения + интересы → "давно не писал X, вот повод" (вышла статья по его теме, etc.)
**6. Wishlist умного дома → совместимость и реализация**
Хотелки + текущий стек (Zigbee, HA версия) → что реально интегрируется, community-решения, очерёдность
**7. Дневник тренировок → инсайты**
Лог активностей + самочувствие + погода → что коррелирует с хорошими результатами, когда лучше тренироваться
**8. Скетчи музыкальных идей → рыночный контекст**
Заметки по трекам (BPM, настроение, референсы) → Spotify анализ похожих, что в тренде в жанре
**9. Список подарков → актуальные варианты**
Профили близких (интересы, что уже есть) × ближайшие даты → marketplace search с обоснованием почему подходит
**10. Wishlist ресторанов → фильтр по контексту**
Список + предпочтения + что уже посетил → фильтр под конкретный контекст (с ребёнком / романтический / деловой), актуальные часы
**11. Темы для изучения → дайджест новостей**
Список интересующих тем → еженедельный дайджест из HN / arxiv / RSS, отфильтрованный от шума под твои конкретные темы
**12. Финансовый watchlist → контекст для решений**
Список активов/инструментов → агрегация сигналов (не трейдинг, а понимание контекста для своих решений)
### Триггеры обогащения
Три способа запускать enrichment:
1. **По добавлению** — новая запись в app-ideas → автоматически запускает анализ
1. **По изменению** — новая запись в списке → автоматически запускает анализ (git diff)
2. **По расписанию** — раз в неделю проходит по спискам, обновляет что устарело
3. **По запросу** — "проведи анализ моих идей приложений"
3. **По запросу** — "проведи анализ по этой теме"
---
@@ -360,13 +360,15 @@ All resolved on GitHub. Fixed in later commits on the `#4544` branch.
---
### 🔴 PR #4664 — Bugbot (RebrandedContextualOnboardingDialogs+SubscriptionPromo.swift:101): Dismiss button appears on standard path
### ✅ [Resolved] PR #4664 — Bugbot (RebrandedContextualOnboardingDialogs+SubscriptionPromo.swift:101): Dismiss button appears on chat path
**Source:** Bugbot on PR #4664, `RebrandedContextualOnboardingDialogs+SubscriptionPromo.swift:101`
**Issue:** Dismiss button is rendered unconditionally, but should only appear on the chat path.
**Issue:** X dismiss button rendered unconditionally on subscription promo dialog; should be hidden on chat path (user should use the dedicated CTA, not escape via X).
**State:** 🔴 [OPEN] on GitHub. Needs a chat-path guard on the dismiss button.
**Fix:** `onManualDismiss` is `(() -> Void)?` in `OnboardingSubscriptionPromoDialog` (line 40, comment: "When `nil` the X dismiss button is hidden (e.g. chat-path onboarding)"). `RebrandedNewTabDaxDialogFactory` passes `nil` when `isChatPath`. Already in code — Bugbot is outdated.
**State:** ✅ Already fixed. GitHub thread status unknown.
---
@@ -504,7 +506,7 @@ All resolved on GitHub. Fixed in later commits on the `#4544` branch.
---
### 🟠 PR #4855 — Alessandro (line 450): Add `!restorePromptHandler.isEligibleForRestorePrompt()` to the returning-user guard
### 🔴 PR #4855 — Alessandro (line 450): Add `!restorePromptHandler.isEligibleForRestorePrompt()` to the returning-user guard
**Source:** [Alessandro May 15 review on PR #4855](https://github.com/duckduckgo/apple-browsers/pull/4855), `OnboardingIntroViewModel.swift:450`. Also referenced in [Alessandro's May 15 Asana comment](https://app.asana.com/1/137249556945/task/1214348462471176/comment/1214794564106665).
@@ -516,6 +518,18 @@ All resolved on GitHub. Fixed in later commits on the `#4544` branch.
---
### 🟠 PR #4855 — Legacy factory: dismiss button shown unconditionally on visit-site dialog
**Source:** Observed during SR feedback pass. Parity issue with `RebrandedNewTabDaxDialogFactory`, which already suppresses the X button on chat path.
**Issue:** `NewTabDaxDialogFactory.createSubsequentDialog` always passed `manualDismissAction` as a non-optional closure to `OnboardingTryVisitingSiteDialog`, so `DaxDialogView` always rendered the X dismiss button — including on the chat path where the user must pick a site and should not be able to escape.
**Fix:** `manualDismissAction` changed to `(() -> Void)? = isChatPath ? nil : { … }`. `OnboardingTryVisitingSiteDialog.onManualDismiss` made `(() -> Void)?` so `DaxDialogView`'s `ifLet(onManualDismiss)` skips the button when `nil`. `ContextualDaxDialogsFactory` (in-browser overlay, always correct to show dismiss) unaffected.
**State:** 🟠 Fix in working tree, NOT committed.
---
### ✅ DEAD-1 — `setChatPathVisitSiteControlsLocked` in `MainViewController+DuckAIExperiment.swift` deleted
**Source:** Callers removed as part of PR #4855 Alessandro (line 477) fix above.