Forge
markdowndeeb25a2
1# ADR 0158: Forge Lens — overlay в CRS (issues/MR по текущему файлу)
2
3**Статус:** Accepted · Implemented
4**Дата:** 2026-06-09
5
6## Резюме
7
8- **Forge Lens** в CIDE — read-only слой **L2** в **CRS** ([0156](0156-correspondence-mfd-surface-and-reverse-code-anchors.md)): issues и merge requests с code anchors на **текущий repo-relative файл**.
9- Конфигурация **только** в `.cascade/workspace.toml` → `[workspace.forge]` (`base_url`, `repo`); Bearer — **device login** (как Intercom OAuth), не вечный PAT в env.
10- Канон API, якорей и MCP-write — **вне репо:** [FORGE-ADR-0003](../../../agent-forge/design/FORGE-ADR-0003-forge-lens-cide-code-anchors.md) (agent-forge).
11- Provenance в CRS: **`forge_lens`** (отдельно от `explicit_toml`, `doc_scan`, …).
12
13## Связанные ADR
14
15| ADR | Роль |
16|-----|------|
17| [0155](0155-documentation-code-correspondence-and-architectural-drift.md) | Слои L0–L4, correspondence kinds |
18| [0156](0156-correspondence-mfd-surface-and-reverse-code-anchors.md) | CRS, reverse anchors, provenance |
19| [0144](0144-intercom-team-transport-cide-sync-and-reference-service.md) | OAuth Connect + secrets TOML (образец) |
20| [0149](0149-settings-toml-pointwise-environment-bindings.md) | `api_token_env` — только DEV override |
21| [0028](0028-user-settings-toml-localappdata-and-secrets.md) | Секреты в `%LocalAppData%\CascadeIDE\` |
22| FORGE-ADR-0010 | `forge auth login`, `~/.forge/credentials.json` |
23| [0157](0157-cide-magic-link-protocol.md) | `cide://`; `forge://` — в FORGE-ADR-0003 |
24| FORGE-ADR-0003 | Lens API, CodeAnchor, MCP-first write |
25| [0159](0159-bracket-forge-artifact-reference.md) | Bracket `[FRG:…]` + code-bracket display |
26| FORGE-ADR-0012 | Forge storage / thin web round-trip |
27
28---
29
30## Контекст
31
32[agent-forge](../../../agent-forge/) хранит issues/MR с **CodeAnchor** (тот же контракт, что [0128](0128-intercom-attachment-anchors-and-code-references.md)). Без клиента в IDE артефакты forge остаются вне correspondence-контура CIDE.
33
34В spike v0 появился клиент `ForgeLensCorrespondenceClient` и секция `[workspace.forge]`, но с **глобальным env-fallback** (`FORGE_BASE_URL`, `FORGE_REPO`, `FORGE_API_TOKEN`). Это скопировано с mental model **MCP-сервера** forge (один процесс = один forge), а не с модели **IDE** (несколько workspace, разные `repo`).
35
36---
37
38## Решение
39
40### 1. Где живёт конфиг
41
42| Поле | Где | Обязательность |
43|------|-----|----------------|
44| `base_url` | `[workspace.forge]` в `.cascade/workspace.toml` | да (для включения Lens) |
45| `repo` | то же | да (имя forge-repo для этого workspace) |
46| `api_token_env` | то же | нет; **только DEV** override ([0149](0149-settings-toml-pointwise-environment-bindings.md)) |
47
48Пример:
49
50```toml
51[workspace.forge]
52base_url = "http://127.0.0.1:8770"
53repo = "cascade-ide"
54```
55
56### 1.1 Auth (канон, v1.1)
57
58По образцу **Intercom** ([0144](0144-intercom-team-transport-cide-sync-and-reference-service.md) §8):
59
60| Шаг | Действие |
61|-----|----------|
62| Connect | `forge_lens.connect` (IDE MCP) или `forge auth login` (CLI) |
63| Approve | браузер `/view/auth/device` или `forge auth approve` (bootstrap один раз) |
64| Хранение CIDE | `%LocalAppData%\CascadeIDE\forge-lens-secrets.toml` |
65| Interop CLI/MCP | `~/.forge/credentials.json` (FORGE-ADR-0010) — читается, если CIDE secrets пусты |
66
67Резолв Bearer для CRS (порядок):
68
691. `forge-lens-secrets.toml` для `base_url`
702. `~/.forge/credentials.json` (тот же host key)
713. `api_token_env` → env (DEV/CI)
724. без Bearer (forge за VPN без `FORGE_REQUIRE_AUTH`)
73
74### 2. CRS integration
75
76- Эндпоинт: `GET /api/v1/repos/{repo}/lens?file={repoRelativePath}` (контракт — FORGE-ADR-0003).
77- Результаты мержатся в `WorkspaceReverseAnchorItems` с `Provenance = forge_lens`.
78- `DocPath` для клика — URL issue/MR на forge (thin web / view); отдельный `forge://` handler — не в scope v1.
79
80### 3. Отклонено: глобальный env-fallback для `base_url` / `repo`
81
82**Не** читаем `FORGE_BASE_URL`, `FORGE_REPO` как запасной источник, если TOML пуст.
83
84| Причина | Пояснение |
85|---------|-----------|
86| Workspace-scoped | У разных открытых solution разные forge-repo; глобальная env одна на машину |
87| Канон CIDE | [0149](0149-settings-toml-pointwise-environment-bindings.md): env — через явный `*_env`, не magic имена |
88| Копируемость | `workspace.toml` коммитится в репо (без секрета); URL/repo — свойства **проекта**, не профиля ОС |
89| Пилот без TOML | Достаточно одной секции в `.cascade/workspace.toml`; не нужен shell profile |
90
91MCP forge по-прежнему может использовать `FORGE_*` в **своём** процессе — это другой продуктовый контур.
92
93### 4. v1 вне scope
94
95- Slash `/forge lens`, `/forge goto` — FORGE-ADR-0003, отдельные задачи.
96- Запись anchors из CIDE — MCP forge, не HTTP из CRS.
97- ERS-строка «forge reachable» — опционально позже.
98
99---
100
101## Последствия
102
103- Без `[workspace.forge]` CRS не показывает forge-слой (молча, как без L1 map).
104- Для auth: один раз `forge_lens.connect`; bootstrap на сервере — как для первого Intercom Connect, не PAT в launch profile.
105- Документация forge ↔ CIDE разделена: FORGE-ADR-0003 (протокол) + этот ADR (IDE overlay).
106
107## Реализация (v1)
108
109| Компонент | Путь |
110|-----------|------|
111| TOML models | `Features/Workspace/WorkspaceTomlModels.cs` — `RepositoryForgeToml` |
112| HTTP client | `ForgeLensCorrespondenceClient.cs` |
113| Credentials | `ForgeLensCredentialResolver.cs`, `ForgeLensSecretsStorage.cs`, `ForgeSharedCredentialReader.cs` |
114| Device login | `ForgeLensDeviceConnectService.cs`, `forge_lens.connect` |
115| CRS merge | `WorkspaceNavigationMapViewModel.Correspondence.cs` |
116
View only · write via MCP/CIDE