ltcai 10.3.0 → 10.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -36
- package/docs/CHANGELOG.md +144 -0
- package/docs/COMMUNITY_AND_PLUGINS.md +1 -1
- package/docs/DEVELOPMENT.md +1 -1
- package/docs/MYPY_BACKLOG.md +59 -92
- package/docs/ONBOARDING.md +1 -1
- package/docs/OPERATIONS.md +1 -1
- package/docs/PERMISSION_MODE.md +15 -4
- package/docs/SURFACE_PARITY.md +33 -6
- package/docs/TRUST_MODEL.md +1 -1
- package/docs/WHY_LATTICE.md +1 -1
- package/docs/kg-schema.md +1 -1
- package/lattice_brain/__init__.py +1 -1
- package/lattice_brain/context.py +23 -3
- package/lattice_brain/graph/_kg_common.py +164 -9
- package/lattice_brain/graph/_kg_contract.py +223 -0
- package/lattice_brain/graph/_kg_fsutil.py +1 -1
- package/lattice_brain/graph/curator.py +4 -4
- package/lattice_brain/graph/discovery.py +12 -1
- package/lattice_brain/graph/discovery_index.py +12 -1
- package/lattice_brain/graph/documents.py +17 -2
- package/lattice_brain/graph/ingest.py +12 -1
- package/lattice_brain/graph/proactive.py +9 -5
- package/lattice_brain/graph/projection.py +12 -1
- package/lattice_brain/graph/provenance.py +12 -1
- package/lattice_brain/graph/retrieval.py +12 -1
- package/lattice_brain/graph/retrieval_docgen.py +12 -1
- package/lattice_brain/graph/retrieval_reads.py +12 -1
- package/lattice_brain/graph/retrieval_vector.py +12 -1
- package/lattice_brain/graph/schema.py +6 -2
- package/lattice_brain/graph/write_master.py +12 -1
- package/lattice_brain/ingestion.py +1 -1
- package/lattice_brain/quality.py +5 -5
- package/lattice_brain/runtime/contracts.py +2 -1
- package/lattice_brain/runtime/multi_agent.py +1 -1
- package/lattice_brain/workflow.py +10 -7
- package/latticeai/__init__.py +1 -1
- package/latticeai/api/admin.py +2 -2
- package/latticeai/api/chat.py +19 -15
- package/latticeai/api/chat_agent_http.py +19 -7
- package/latticeai/api/chat_helpers.py +9 -8
- package/latticeai/api/chat_stream.py +2 -2
- package/latticeai/api/computer_use.py +2 -2
- package/latticeai/api/hooks.py +4 -2
- package/latticeai/api/local_files.py +8 -4
- package/latticeai/api/mcp.py +2 -2
- package/latticeai/api/models.py +5 -5
- package/latticeai/api/permissions.py +2 -2
- package/latticeai/api/search.py +5 -3
- package/latticeai/api/security_dashboard.py +3 -5
- package/latticeai/api/setup.py +3 -3
- package/latticeai/api/static_routes.py +7 -2
- package/latticeai/api/tools.py +9 -4
- package/latticeai/api/workspace.py +25 -22
- package/latticeai/app_factory.py +132 -1322
- package/latticeai/cli/entrypoint.py +1 -1
- package/latticeai/core/agent.py +28 -14
- package/latticeai/core/audit.py +5 -3
- package/latticeai/core/embedding_providers.py +19 -6
- package/latticeai/core/legacy_compatibility.py +1 -1
- package/latticeai/core/marketplace.py +2 -2
- package/latticeai/core/mcp_catalog.py +3 -1
- package/latticeai/core/model_compat.py +1 -1
- package/latticeai/core/plugins.py +1 -1
- package/latticeai/core/project_sessions.py +1 -1
- package/latticeai/core/run_explain.py +6 -4
- package/latticeai/core/workspace_os.py +0 -4
- package/latticeai/core/workspace_os_constants.py +1 -1
- package/latticeai/core/workspace_os_state.py +1 -1
- package/latticeai/core/workspace_snapshots.py +3 -3
- package/latticeai/integrations/telegram_bot.py +52 -3
- package/latticeai/models/router.py +61 -34
- package/latticeai/runtime/access_runtime.py +3 -1
- package/latticeai/runtime/build_phases.py +1417 -0
- package/latticeai/runtime/review_wiring.py +6 -1
- package/latticeai/runtime/runtime_context.py +276 -0
- package/latticeai/runtime/sso_config_runtime.py +1 -1
- package/latticeai/runtime/stages.py +8 -2
- package/latticeai/services/app_context.py +23 -0
- package/latticeai/services/architecture_readiness.py +1 -1
- package/latticeai/services/brain_intelligence.py +4 -2
- package/latticeai/services/cloud_streaming.py +5 -3
- package/latticeai/services/command_center.py +1 -1
- package/latticeai/services/evidence_actions.py +2 -1
- package/latticeai/services/hybrid_chat.py +1 -1
- package/latticeai/services/local_knowledge.py +25 -9
- package/latticeai/services/memory_service.py +8 -4
- package/latticeai/services/model_catalog.py +12 -12
- package/latticeai/services/model_engines.py +15 -17
- package/latticeai/services/model_loading.py +1 -1
- package/latticeai/services/model_runtime.py +31 -33
- package/latticeai/services/multimodal_streaming.py +10 -4
- package/latticeai/services/openai_compatible_adapter.py +4 -3
- package/latticeai/services/product_readiness.py +1 -1
- package/latticeai/services/run_executor.py +12 -3
- package/latticeai/services/search_service.py +1 -1
- package/latticeai/services/triggers.py +1 -1
- package/latticeai/setup/auto_setup.py +1 -1
- package/latticeai/setup/wizard.py +12 -3
- package/latticeai/tools/computer.py +3 -1
- package/latticeai/tools/documents.py +2 -2
- package/package.json +1 -1
- package/scripts/capture_release_evidence.mjs +32 -8
- package/scripts/check_current_release_docs.mjs +1 -1
- package/src-tauri/Cargo.lock +1 -1
- package/src-tauri/Cargo.toml +1 -1
- package/src-tauri/tauri.conf.json +1 -1
- package/static/app/asset-manifest.json +38 -38
- package/static/app/assets/{Act-DrKIGZeJ.js → Act-CLsUUE4V.js} +1 -1
- package/static/app/assets/{AdminConsole-CEV1VefA.js → AdminConsole-D1PBR5Mk.js} +1 -1
- package/static/app/assets/{Brain-BZSXnwWU.js → Brain-Cnb_YCYH.js} +2 -2
- package/static/app/assets/BrainHome-DMMhKb8j.js +2 -0
- package/static/app/assets/{BrainSignals-O4s6R7av.js → BrainSignals-CcvYpBGn.js} +1 -1
- package/static/app/assets/Capture-DU1HZWqB.js +1 -0
- package/static/app/assets/{CommandPalette-CeqBjCn2.js → CommandPalette-tU229JbI.js} +1 -1
- package/static/app/assets/Library-BeutJd8j.js +1 -0
- package/static/app/assets/{LivingBrain-D9Iei2ZJ.js → LivingBrain-BVFU-llN.js} +1 -1
- package/static/app/assets/{ProductFlow-JlXiDfMM.js → ProductFlow-CZp8oHh_.js} +1 -1
- package/static/app/assets/{ReviewCard-QQly2bTV.js → ReviewCard-DODh3z_D.js} +1 -1
- package/static/app/assets/System-CTYfZXfv.js +1 -0
- package/static/app/assets/{activity-CxRPOQ2F.js → activity-DYlZpTrt.js} +1 -1
- package/static/app/assets/{bot-1bcsWB2s.js → bot-BBmfPYKv.js} +1 -1
- package/static/app/assets/brain-RRpEg40e.js +1 -0
- package/static/app/assets/{button-ZYFqGan7.js → button-DXSLgXUl.js} +1 -1
- package/static/app/assets/{circle-pause-B5NOIqvk.js → circle-pause-B8TPRvnt.js} +1 -1
- package/static/app/assets/{circle-play-BiJVFXf7.js → circle-play-C5aQnYUv.js} +1 -1
- package/static/app/assets/{cpu-Vvq0OKTr.js → cpu-BvOUS0hg.js} +1 -1
- package/static/app/assets/{download-SEcXzkx1.js → download-BM2Y4baa.js} +1 -1
- package/static/app/assets/{folder-open-Dw1ff_Qa.js → folder-open-DATq5giq.js} +1 -1
- package/static/app/assets/{hard-drive-B00fR7_r.js → hard-drive-D2iumtyP.js} +1 -1
- package/static/app/assets/{index-CEkL4_M-.css → index-B1n87vO-.css} +1 -1
- package/static/app/assets/{index-Dm9VXl1o.js → index-D10Yd0gh.js} +3 -3
- package/static/app/assets/{input-DtdWYQEa.js → input-Ptpha52f.js} +1 -1
- package/static/app/assets/permissionCopy-DLSOKW1h.js +1 -0
- package/static/app/assets/{primitives-CwsudBwc.js → primitives-BvxTiz4R.js} +1 -1
- package/static/app/assets/search-DtMikKf0.js +1 -0
- package/static/app/assets/{shield-alert-CpjBc-gQ.js → shield-alert-B6RHxSXi.js} +1 -1
- package/static/app/assets/{textarea-DUPyjHQs.js → textarea-CCZqVitr.js} +1 -1
- package/static/app/assets/{useFocusTrap-BWcMtCWH.js → useFocusTrap-QR9BiUDX.js} +1 -1
- package/static/app/assets/{useQuery-Dg5fPqTS.js → useQuery-B42HOaUm.js} +1 -1
- package/static/app/assets/{users-BgcdTQGM.js → users-D9PLGmAE.js} +1 -1
- package/static/app/assets/{utils-a3YXFtEO.js → utils-CAuwfT8i.js} +1 -1
- package/static/app/assets/workspace-DT2v1d3T.js +1 -0
- package/static/app/index.html +4 -4
- package/static/sw.js +1 -1
- package/static/app/assets/BrainHome-CEBd86k6.js +0 -2
- package/static/app/assets/Capture-AGbOxsg-.js +0 -1
- package/static/app/assets/Library-CXnbNiQW.js +0 -1
- package/static/app/assets/System-Bp9ZY4ER.js +0 -1
- package/static/app/assets/brain-CxaeKCRM.js +0 -1
- package/static/app/assets/network-CpjBu0kI.js +0 -1
- package/static/app/assets/search-CwEJWBEA.js +0 -1
- package/static/app/assets/workspace-BMUEiXUm.js +0 -1
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
[](https://github.com/TaeSooPark-PTS/LatticeAI/actions/workflows/ci.yml)
|
|
12
12
|
[](LICENSE)
|
|
13
13
|
|
|
14
|
-

|
|
15
15
|
|
|
16
16
|
Chat, files, folders, notes, and web pages all flow into one durable knowledge
|
|
17
17
|
graph on your computer. Any model — local MLX or cloud — can speak with that
|
|
@@ -24,9 +24,10 @@ memory. Nothing leaves your machine without explicit consent.
|
|
|
24
24
|
|
|
25
25
|
| | |
|
|
26
26
|
| --- | --- |
|
|
27
|
-
| **Chat with a Brain that remembers** — every conversation grows durable, source-linked memory  | **See how knowledge connects** — a real relationship graph, not a file list  |
|
|
28
|
+
| **Capture anything** — files, whole folders, notes, screenshots, web pages  | **Automate with review** — agent changes become proposals you approve first  |
|
|
29
|
+
| **Pick a model in one click** — recommended local models for your hardware  | **Stay in control** — audit, roles, retention in a separate admin surface  |
|
|
30
|
+
| **Watch a file become memory** — three named steps, not a pipeline diagram  | **Say how much it may do alone** — one dial in plain words; dangerous actions stay blocked either way  |
|
|
30
31
|
|
|
31
32
|
## Why Lattice AI
|
|
32
33
|
|
|
@@ -57,47 +58,55 @@ First-run flow — wake the Brain, pick the owner, load a recommended model:
|
|
|
57
58
|
|
|
58
59
|
| | | |
|
|
59
60
|
| --- | --- | --- |
|
|
60
|
-
|  |  |  |
|
|
61
62
|
|
|
62
63
|
Screenshot index and capture notes:
|
|
63
|
-
[output/release/v10.
|
|
64
|
+
[output/release/v10.5.0/SCREENSHOT_INDEX.md](output/release/v10.5.0/SCREENSHOT_INDEX.md)
|
|
64
65
|
|
|
65
66
|
## Current Release
|
|
66
67
|
|
|
67
|
-
The current release is **10.
|
|
68
|
-
|
|
69
|
-
10.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
- **
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
68
|
+
The current release is **10.5.0 — Everyday Words**:
|
|
69
|
+
|
|
70
|
+
10.4.0 named the ground the code stands on. 10.5.0 renames the ground the
|
|
71
|
+
*reader* stands on: every screen a first-time user lands on now says what
|
|
72
|
+
Lattice is doing in the words that user would use. No feature was removed —
|
|
73
|
+
the engine's own vocabulary moved behind the advanced mode switch, where it
|
|
74
|
+
belongs to the people who asked for it.
|
|
75
|
+
|
|
76
|
+
- **The autonomy dial is a sentence, not a mode name.** 엄격 / 신뢰 / 바이패스
|
|
77
|
+
became 먼저 물어보기 / 웬만하면 알아서 / 거의 다 알아서, each with one line
|
|
78
|
+
about what it will and will not do on its own. The home dial and Settings
|
|
79
|
+
now draw that copy from one module, so the same setting is never named two
|
|
80
|
+
ways — and a mode the server adds later still renders, from the server's own
|
|
81
|
+
label.
|
|
82
|
+
- **The path from a file to a memory is three named steps.** 진행 상황 was
|
|
83
|
+
hidden from plain mode and held two raw API payloads. It now shows
|
|
84
|
+
내용 읽기 → 뜻 파악하기 → 기억에 연결하기 as a labelled ordered list, with
|
|
85
|
+
each step saying what it does to your file. 파싱 · 임베딩 · 인덱싱 are gone
|
|
86
|
+
from that screen.
|
|
87
|
+
- **Automations are named the way you named them.** A run shows its workflow's
|
|
88
|
+
name rather than a database id, and its state is spoken — `awaiting_approval`
|
|
89
|
+
reads as "내 승인 기다리는 중". Unknown states say so instead of printing the
|
|
90
|
+
token. Advanced mode still shows the id.
|
|
91
|
+
- **A model your machine cannot run says so in one sentence** instead of a
|
|
92
|
+
registry line half-translated word by word.
|
|
93
|
+
- **The published screenshots were wrong before this release.** Capture ran in
|
|
94
|
+
`advanced`, so every README frame showed payload panels, storage engines and
|
|
95
|
+
hook logs that no first-run user is ever shown. Captures now run in the app's
|
|
96
|
+
real default, `basic` — this page's images are what you will actually see.
|
|
97
|
+
- **Guarded, not asserted.** A visual sweep walks ten plain-mode routes and
|
|
98
|
+
fails if any of them renders empty or puts engine vocabulary in front of a
|
|
99
|
+
reader who never asked for it.
|
|
91
100
|
|
|
92
101
|
Release notes: [RELEASE.md](RELEASE.md) · Full history: [docs/CHANGELOG.md](docs/CHANGELOG.md)
|
|
93
102
|
|
|
94
|
-
Expected artifacts for 10.
|
|
103
|
+
Expected artifacts for 10.5.0 release must use exact filenames:
|
|
95
104
|
|
|
96
|
-
- `dist/ltcai-10.
|
|
97
|
-
- `dist/ltcai-10.
|
|
98
|
-
- `ltcai-10.
|
|
99
|
-
- `dist/ltcai-10.
|
|
100
|
-
- `src-tauri/target/release/bundle/dmg/Lattice AI_10.
|
|
105
|
+
- `dist/ltcai-10.5.0-py3-none-any.whl`
|
|
106
|
+
- `dist/ltcai-10.5.0.tar.gz`
|
|
107
|
+
- `ltcai-10.5.0.tgz`
|
|
108
|
+
- `dist/ltcai-10.5.0.vsix`
|
|
109
|
+
- `src-tauri/target/release/bundle/dmg/Lattice AI_10.5.0_aarch64.dmg`
|
|
101
110
|
|
|
102
111
|
Do not use wildcard artifact uploads. Package registry publishing remains owner-run.
|
|
103
112
|
|
|
@@ -132,6 +141,8 @@ See [ARCHITECTURE.md](ARCHITECTURE.md) for details and
|
|
|
132
141
|
|
|
133
142
|
| Version | Theme |
|
|
134
143
|
| --- | --- |
|
|
144
|
+
| 10.5.0 | Everyday Words |
|
|
145
|
+
| 10.4.0 | Named Ground |
|
|
135
146
|
| 10.3.0 | Measured Ground |
|
|
136
147
|
| 10.2.0 | Load-Bearing Fixes |
|
|
137
148
|
| 10.1.1 | Reachable Boundary |
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,150 @@ The top entry is either the current unreleased main-branch work or the current
|
|
|
4
4
|
release line. Older entries are historical and may describe behavior as it
|
|
5
5
|
existed at that release.
|
|
6
6
|
|
|
7
|
+
## [10.5.0] - 2026-08-03
|
|
8
|
+
|
|
9
|
+
A UI/UX pass for the person who did not build this. No feature was removed;
|
|
10
|
+
vocabulary, ordering, and the default mode a first-run user lands in changed.
|
|
11
|
+
Backend behaviour is unchanged — `frontend/openapi.json` differs from 10.4.0
|
|
12
|
+
only in `info.version`.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
- **Permission modes are named by what they do to you, not by their enum.**
|
|
16
|
+
엄격 / 신뢰 / 바이패스 → 먼저 물어보기 / 웬만하면 알아서 / 거의 다 알아서
|
|
17
|
+
(`Strict` / `Trusted` / `Bypass` → `Ask me first` / `Mostly on its own` /
|
|
18
|
+
`Almost everything on its own`), each with a one-line summary of what it does
|
|
19
|
+
without asking. The bypass warning now says which kind of action stays
|
|
20
|
+
blocked rather than naming the mode.
|
|
21
|
+
- **`#/pipeline` is reachable in basic mode and named 진행 상황.** Its two raw
|
|
22
|
+
API payload panels are replaced (in basic mode) by an `aria-label`ed ordered
|
|
23
|
+
list of three steps — 내용 읽기 / 뜻 파악하기 / 기억에 연결하기 — with a
|
|
24
|
+
per-step waiting/working/done state. Advanced mode keeps both payload panels.
|
|
25
|
+
- **Ingestion stage names describe the reader's file, not the machine's job**:
|
|
26
|
+
준비 → 파일 여는 중, 파싱 → 내용 읽는 중, 임베딩 → 뜻 파악하는 중, 인덱싱 →
|
|
27
|
+
기억에 연결하는 중, 메모리화 완료 → 기억 완료. The stale-embedding prompt
|
|
28
|
+
became "찾는 방식이 바뀌었어요 / 기억 다시 정리하기".
|
|
29
|
+
- **Run rows are titled by workflow name** (then goal, then title/query, then
|
|
30
|
+
"n번째 작업" in basic mode) instead of a database id; the id moves to a
|
|
31
|
+
secondary line in advanced mode only.
|
|
32
|
+
- **Run and trigger states are translated per token.**
|
|
33
|
+
`act.runStatus.<token>` covers ok/succeeded/completed/retried_ok/
|
|
34
|
+
awaiting_approval/waiting_approval/running/queued/pending/failed/error/
|
|
35
|
+
cancelled/stopped/interrupted/rejected/partial; an unmapped token renders
|
|
36
|
+
"알 수 없음" rather than itself.
|
|
37
|
+
- **Brain stats answer a person's question** — 저장 위치 / 내 컴퓨터 and
|
|
38
|
+
가져가기 / 언제든 내보낼 수 있어요 in place of `schema_version` and the
|
|
39
|
+
storage engine name (both still shown in advanced).
|
|
40
|
+
- **`scripts/capture_release_evidence.mjs` captures in `basic`**, the app's real
|
|
41
|
+
default, instead of `advanced`. Every README screenshot before this release
|
|
42
|
+
showed panels a first-run user never sees. `09-model-setup-status.png` (a
|
|
43
|
+
duplicate of the Brain home once captured in basic) is replaced by
|
|
44
|
+
`09-automation-runs.png`, and `11-knowledge-journey.png` is added.
|
|
45
|
+
- **The walkthrough GIF is encoded against a palette generated from the clip**
|
|
46
|
+
(`palettegen=stats_mode=diff` + `paletteuse=dither=sierra2_4a`) instead of
|
|
47
|
+
ffmpeg's default 256-colour cube, which had been rendering the ivory
|
|
48
|
+
background as dithered yellow and the greens as olive. 1.5 MB → 2.8 MB.
|
|
49
|
+
|
|
50
|
+
### Added
|
|
51
|
+
- `frontend/src/lib/permissionCopy.ts` — one source for permission-mode copy,
|
|
52
|
+
shared by `BrainQuickControls` (home dial) and `PermissionModePanel`
|
|
53
|
+
(Settings), which had each been translating the server catalog separately.
|
|
54
|
+
Lookup is by mode id, falling back to the server's own localized label, so a
|
|
55
|
+
mode added server-side still renders; `PermissionModePanel.test.tsx` asserts
|
|
56
|
+
that fallback so the table cannot become an accidental allowlist.
|
|
57
|
+
- A basic-mode "자동으로 실행되는 작업" summary on the workflows surface:
|
|
58
|
+
workflow name plus 새 자료가 들어오면 / 정해진 시간에 / 내가 눌렀을 때만 /
|
|
59
|
+
조건이 맞으면, and 켜져 있어요 / 지금은 멈춰 있어요. The node canvas and the
|
|
60
|
+
paste-JSON box are author tools and stay in advanced mode.
|
|
61
|
+
- `tests/visual/v3.spec.js`: a sweep over ten plain-mode routes asserting each
|
|
62
|
+
renders, shows no service-unavailable banner, and contains none of a list of
|
|
63
|
+
engine terms; plus a test that the three journey steps render under their
|
|
64
|
+
accessible name. `#/runs` failed the vocabulary assertion before this pass.
|
|
65
|
+
- `Library.test.tsx` covers registry prose that is English-only: a sentence with
|
|
66
|
+
no Hangul and six or more words is now replaced by a written Korean
|
|
67
|
+
explanation instead of being substituted term by term into word salad.
|
|
68
|
+
|
|
69
|
+
### Known gaps
|
|
70
|
+
- The approval card under 작업 → 실행 still labels raw payload fields `Action`,
|
|
71
|
+
`Action Label`, `User Email`. It is visible in `09-automation-runs.png` and is
|
|
72
|
+
published rather than cropped.
|
|
73
|
+
|
|
74
|
+
## [10.4.0] - 2026-08-02
|
|
75
|
+
|
|
76
|
+
### Changed
|
|
77
|
+
- **`app_factory._build` is decomposed.** 1,318 lines → 26. The assembly now
|
|
78
|
+
lives in `latticeai/runtime/build_phases.py` as ten ordered phases sharing a
|
|
79
|
+
typed `latticeai/runtime/runtime_context.py::RuntimeContext`:
|
|
80
|
+
`platform → config → identity → brain → domain → web → services →
|
|
81
|
+
foundation_routes → platform_features → interaction`.
|
|
82
|
+
The single closure worked because closures resolve free variables at call
|
|
83
|
+
time; several sections depend on names bound far below them. The
|
|
84
|
+
RuntimeContext preserves that late binding while naming the shared state.
|
|
85
|
+
`tests/unit/test_runtime_context.py` fixes the phase order, which phase
|
|
86
|
+
produces which attribute, and that reading one early fails by name.
|
|
87
|
+
- **mypy covers the whole tree: 274 of 274 modules, 0 errors** (was 193 of 270
|
|
88
|
+
with 1,407 outstanding). `pyproject.toml`'s `[tool.mypy] files` is no longer
|
|
89
|
+
a curated subset.
|
|
90
|
+
- `lattice_brain/graph/_kg_common.py`'s `__all__` is a literal instead of a
|
|
91
|
+
comprehension over `globals()`. The computed form was invisible to a type
|
|
92
|
+
checker, so twelve modules resolved no names behind
|
|
93
|
+
`from ._kg_common import *` (~750 false `name-defined` errors).
|
|
94
|
+
`tests/unit/test_kg_common_exports.py` keeps the literal honest.
|
|
95
|
+
- The star import of `._kg_fsutil` inside `_kg_common` is now an explicit list
|
|
96
|
+
for the same reason.
|
|
97
|
+
- JSON-shaped payloads in `services/model_runtime.py`, `model_engines.py`,
|
|
98
|
+
`model_catalog.py`, `api/setup.py` and `api/models.py` are typed
|
|
99
|
+
`Dict[str, Any]` rather than `Dict[str, object]`, which forced a cast at
|
|
100
|
+
every nested access without catching anything.
|
|
101
|
+
- Optional dependencies (`AsyncOpenAI`, `mx`, `vlm_load`, `lm_load`,
|
|
102
|
+
`pyautogui`) are aliased on import and re-exported as `Any`, so "installed"
|
|
103
|
+
and "absent" have one declared type.
|
|
104
|
+
|
|
105
|
+
### Added
|
|
106
|
+
- `lattice_brain/graph/_kg_contract.py` — the 23-member surface the eleven
|
|
107
|
+
graph mixins share, written down for the first time. Typing-only: `_Core` is
|
|
108
|
+
`object` at runtime, so `KnowledgeGraphStore`'s MRO is unchanged.
|
|
109
|
+
`tests/unit/test_kg_contract.py` asserts both the contract and that it never
|
|
110
|
+
becomes a real base class.
|
|
111
|
+
- `AppContext.require(field)` — binds a dependency a router cannot run without,
|
|
112
|
+
so an absent one names itself at router construction instead of surfacing as
|
|
113
|
+
`'NoneType' object is not callable` inside a request handler.
|
|
114
|
+
- VS Code `ltcai.captureFolder` — folder ingestion through the same
|
|
115
|
+
`/api/ingestion/folder` endpoint and the same local-read approval dance the
|
|
116
|
+
web Capture view uses.
|
|
117
|
+
- VS Code `ltcai.showArtifacts` — `artifacts[]` rendered as cards with the
|
|
118
|
+
server's repair and validation flags, so a deterministically repaired
|
|
119
|
+
scaffold no longer looks identical to clean model output.
|
|
120
|
+
- VS Code model picker now shows the hardware-derived recommendation from
|
|
121
|
+
`GET /setup/scan`, with the server's own reasoning. No scan, no banner.
|
|
122
|
+
- Telegram sends the same `artifacts[]` card summary before the files.
|
|
123
|
+
- Frontend tests for four previously untested modules with real logic:
|
|
124
|
+
`routes.ts`, `store/appStore.ts`, `api/base.ts` error translation, and
|
|
125
|
+
`pages/brain/graphExplorer.ts`.
|
|
126
|
+
|
|
127
|
+
### Fixed
|
|
128
|
+
- **`python -m latticeai.server_app` raised `AttributeError`.** `main` was a
|
|
129
|
+
local inside the old `_build` closure and was never on the export allowlist,
|
|
130
|
+
so `get_shared_runtime().main()` could never resolve it. `main()` now serves
|
|
131
|
+
the shared runtime directly and needs no export.
|
|
132
|
+
- `core/workspace_os.py`: four lines duplicated after a `return` in
|
|
133
|
+
`remove_member` — dead since the merge that introduced them.
|
|
134
|
+
- `models/router.py`: a `str` shadowed a `dict` in the custom cloud-model loop,
|
|
135
|
+
so those entries built their ids from the wrong variable.
|
|
136
|
+
- `lattice_brain/context.py`: an unconfigured retrieval seam was called
|
|
137
|
+
unguarded and died as a `TypeError` inside failure isolation instead of
|
|
138
|
+
naming itself.
|
|
139
|
+
- `runtime/review_wiring.py` declared its injected `HTTPException` as
|
|
140
|
+
`type[Exception]`, which does not accept `(status_code=, detail=)`.
|
|
141
|
+
- `api/security_dashboard.py`: a defensive `isinstance(rows, list)` re-check
|
|
142
|
+
that every branch above already guaranteed.
|
|
143
|
+
|
|
144
|
+
### Documentation
|
|
145
|
+
- `docs/MYPY_BACKLOG.md` is now the record of how the boundary closed, not a
|
|
146
|
+
list of what is left — including the conventions the sweep settled on.
|
|
147
|
+
- `docs/SURFACE_PARITY.md`: no ◐ remains in the matrix. A stale v9.9.6 note
|
|
148
|
+
claiming the live step timeline was web-only is corrected (v9.9.7's
|
|
149
|
+
`runAgentLive` provides it).
|
|
150
|
+
|
|
7
151
|
## [10.3.0] - 2026-07-29
|
|
8
152
|
|
|
9
153
|
### Fixed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Community And Plugins
|
|
2
2
|
|
|
3
|
-
Current release: **10.
|
|
3
|
+
Current release: **10.5.0 — Everyday Words**.
|
|
4
4
|
|
|
5
5
|
LatticeAI defines the path from a strong local-first framework (8.4.0
|
|
6
6
|
action-aware baseline, 8.5.0 registry+DI hardening, 8.6.0 capture/navigation
|
package/docs/DEVELOPMENT.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
> **Status: canonical** — current contributor guidance, kept in sync with the
|
|
4
4
|
> current release.
|
|
5
5
|
|
|
6
|
-
Current release: **10.
|
|
6
|
+
Current release: **10.5.0 — Everyday Words**.
|
|
7
7
|
|
|
8
8
|
This document is for contributors working on the local-first Digital Brain
|
|
9
9
|
codebase. Product positioning and quick start stay in `README.md`; release
|
package/docs/MYPY_BACKLOG.md
CHANGED
|
@@ -1,98 +1,65 @@
|
|
|
1
1
|
# mypy backlog
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
fact rather than an open-ended intention.
|
|
3
|
+
> **Status: reference**
|
|
4
|
+
> 10.2.0: 13 modules checked. 10.3.0: 193 of 270, with the remaining 77 listed
|
|
5
|
+
> here by error count. **10.4.0: 274 of 274 — the backlog is empty.**
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
`[tool.mypy] files` in `pyproject.toml` now lists **every** module in
|
|
8
|
+
`lattice_brain/` and `latticeai/`. There is no "adopted set" any more; adding a
|
|
9
|
+
module to the tree adds it to the checked set, and CI fails if it does not
|
|
10
|
+
type-check.
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
unreadable registry, `_kg_fsutil.py` used `Iterable` without importing it,
|
|
15
|
-
and `agent_runtime.py` called `.get` on a value that could be `None`. Those
|
|
16
|
-
are fixed; the list below is what is left.
|
|
12
|
+
This file stays as the record of how the boundary closed, because two of the
|
|
13
|
+
1,407 errors 10.3.0 measured turned out to be worth more than the annotations.
|
|
17
14
|
|
|
18
|
-
|
|
19
|
-
| ---: | --- | --- |
|
|
20
|
-
| 1 | `lattice_brain/graph/_kg_fsutil.py` | `union-attr` ×1 |
|
|
21
|
-
| 1 | `latticeai/api/admin.py` | `call-overload` ×1 |
|
|
22
|
-
| 1 | `latticeai/api/computer_use.py` | `var-annotated` ×1 |
|
|
23
|
-
| 1 | `latticeai/api/hooks.py` | `unreachable` ×1 |
|
|
24
|
-
| 1 | `latticeai/api/local_files.py` | `arg-type` ×1 |
|
|
25
|
-
| 1 | `latticeai/api/static_routes.py` | `assignment` ×1 |
|
|
26
|
-
| 1 | `latticeai/core/marketplace.py` | `arg-type` ×1 |
|
|
27
|
-
| 1 | `latticeai/core/model_compat.py` | `unreachable` ×1 |
|
|
28
|
-
| 1 | `latticeai/core/plugins.py` | `unreachable` ×1 |
|
|
29
|
-
| 1 | `latticeai/core/project_sessions.py` | `var-annotated` ×1 |
|
|
30
|
-
| 1 | `latticeai/core/workspace_os.py` | `unreachable` ×1 |
|
|
31
|
-
| 1 | `latticeai/core/workspace_os_state.py` | `arg-type` ×1 |
|
|
32
|
-
| 1 | `latticeai/runtime/sso_config_runtime.py` | `arg-type` ×1 |
|
|
33
|
-
| 1 | `latticeai/services/command_center.py` | `assignment` ×1 |
|
|
34
|
-
| 1 | `latticeai/services/search_service.py` | `assignment` ×1 |
|
|
35
|
-
| 1 | `latticeai/services/triggers.py` | `truthy-function` ×1 |
|
|
36
|
-
| 1 | `latticeai/setup/auto_setup.py` | `attr-defined` ×1 |
|
|
37
|
-
| 2 | `lattice_brain/ingestion.py` | `assignment` ×2 |
|
|
38
|
-
| 2 | `latticeai/api/chat_stream.py` | `var-annotated` ×1, `arg-type` ×1 |
|
|
39
|
-
| 2 | `latticeai/api/mcp.py` | `var-annotated` ×2 |
|
|
40
|
-
| 2 | `latticeai/core/mcp_registry.py` | `index` ×1, `return-value` ×1 |
|
|
41
|
-
| 2 | `latticeai/core/run_explain.py` | `union-attr` ×1, `call-overload` ×1 |
|
|
42
|
-
| 2 | `latticeai/core/workspace_snapshots.py` | `var-annotated` ×2 |
|
|
43
|
-
| 2 | `latticeai/runtime/review_wiring.py` | `call-arg` ×2 |
|
|
44
|
-
| 2 | `latticeai/services/brain_intelligence.py` | `operator` ×1, `index` ×1 |
|
|
45
|
-
| 2 | `latticeai/services/memory_service.py` | `misc` ×1, `index` ×1 |
|
|
46
|
-
| 2 | `latticeai/services/model_loading.py` | `arg-type` ×1, `call-overload` ×1 |
|
|
47
|
-
| 2 | `latticeai/services/multimodal_streaming.py` | `attr-defined` ×1, `arg-type` ×1 |
|
|
48
|
-
| 2 | `latticeai/setup/wizard.py` | `attr-defined` ×1, `dict-item` ×1 |
|
|
49
|
-
| 2 | `latticeai/tools/documents.py` | `arg-type` ×2 |
|
|
50
|
-
| 3 | `lattice_brain/quality.py` | `var-annotated` ×2, `return-value` ×1 |
|
|
51
|
-
| 3 | `latticeai/api/models.py` | `call-overload` ×2, `attr-defined` ×1 |
|
|
52
|
-
| 3 | `latticeai/cli/entrypoint.py` | `operator` ×1, `union-attr` ×1, `arg-type` ×1 |
|
|
53
|
-
| 3 | `latticeai/core/audit.py` | `assignment` ×1, `index` ×1, `operator` ×1 |
|
|
54
|
-
| 3 | `latticeai/integrations/telegram_bot.py` | `union-attr` ×2, `arg-type` ×1 |
|
|
55
|
-
| 3 | `latticeai/runtime/stages.py` | `arg-type` ×3 |
|
|
56
|
-
| 3 | `latticeai/services/cloud_streaming.py` | `arg-type` ×2, `attr-defined` ×1 |
|
|
57
|
-
| 3 | `latticeai/services/hybrid_chat.py` | `arg-type` ×3 |
|
|
58
|
-
| 3 | `latticeai/services/tool_dispatch.py` | `arg-type` ×3 |
|
|
59
|
-
| 4 | `lattice_brain/graph/_kg_common.py` | `misc` ×3, `return-value` ×1 |
|
|
60
|
-
| 4 | `latticeai/api/chat_agent_http.py` | `arg-type` ×2, `misc` ×1, `assignment` ×1 |
|
|
61
|
-
| 4 | `latticeai/api/chat_helpers.py` | `call-overload` ×2, `union-attr` ×1, `arg-type` ×1 |
|
|
62
|
-
| 4 | `latticeai/api/security_dashboard.py` | `assignment` ×3, `unreachable` ×1 |
|
|
63
|
-
| 4 | `latticeai/services/evidence_actions.py` | `union-attr` ×4 |
|
|
64
|
-
| 5 | `lattice_brain/context.py` | `arg-type` ×4, `misc` ×1 |
|
|
65
|
-
| 5 | `latticeai/api/permissions.py` | `arg-type` ×5 |
|
|
66
|
-
| 5 | `latticeai/services/model_engines.py` | `attr-defined` ×2, `call-overload` ×2, `unreachable` ×1 |
|
|
67
|
-
| 5 | `latticeai/services/run_executor.py` | `unreachable` ×3, `arg-type` ×1, `return-value` ×1 |
|
|
68
|
-
| 6 | `lattice_brain/runtime/contracts.py` | `union-attr` ×6 |
|
|
69
|
-
| 6 | `latticeai/core/agent.py` | `arg-type` ×4, `return-value` ×2 |
|
|
70
|
-
| 7 | `lattice_brain/graph/proactive.py` | `assignment` ×2, `arg-type` ×2, `index` ×1 |
|
|
71
|
-
| 7 | `latticeai/app_factory.py` | `arg-type` ×3, `assignment` ×2, `attr-defined` ×2 |
|
|
72
|
-
| 7 | `latticeai/core/embedding_providers.py` | `unreachable` ×2, `assignment` ×2, `union-attr` ×2 |
|
|
73
|
-
| 7 | `latticeai/services/openai_compatible_adapter.py` | `arg-type` ×7 |
|
|
74
|
-
| 8 | `lattice_brain/graph/curator.py` | `operator` ×8 |
|
|
75
|
-
| 8 | `lattice_brain/workflow.py` | `arg-type` ×5, `index` ×2, `assignment` ×1 |
|
|
76
|
-
| 8 | `latticeai/api/setup.py` | `index` ×5, `attr-defined` ×3 |
|
|
77
|
-
| 8 | `latticeai/services/local_knowledge.py` | `union-attr` ×3, `misc` ×2, `operator` ×2 |
|
|
78
|
-
| 10 | `latticeai/api/tools.py` | `arg-type` ×10 |
|
|
79
|
-
| 13 | `latticeai/api/search.py` | `return` ×12, `return-value` ×1 |
|
|
80
|
-
| 15 | `lattice_brain/graph/store.py` | `name-defined` ×15 |
|
|
81
|
-
| 16 | `latticeai/api/chat.py` | `arg-type` ×12, `misc` ×3, `call-overload` ×1 |
|
|
82
|
-
| 16 | `latticeai/tools/computer.py` | `union-attr` ×16 |
|
|
83
|
-
| 19 | `lattice_brain/graph/retrieval_docgen.py` | `name-defined` ×12, `attr-defined` ×7 |
|
|
84
|
-
| 35 | `latticeai/services/model_runtime.py` | `index` ×15, `arg-type` ×8, `attr-defined` ×6 |
|
|
85
|
-
| 45 | `lattice_brain/graph/retrieval_reads.py` | `name-defined` ×30, `attr-defined` ×15 |
|
|
86
|
-
| 46 | `latticeai/models/router.py` | `arg-type` ×26, `assignment` ×7, `attr-defined` ×4 |
|
|
87
|
-
| 57 | `lattice_brain/graph/write_master.py` | `name-defined` ×48, `attr-defined` ×9 |
|
|
88
|
-
| 64 | `lattice_brain/graph/documents.py` | `name-defined` ×45, `attr-defined` ×19 |
|
|
89
|
-
| 71 | `lattice_brain/graph/provenance.py` | `name-defined` ×59, `attr-defined` ×12 |
|
|
90
|
-
| 77 | `lattice_brain/graph/retrieval.py` | `name-defined` ×61, `attr-defined` ×16 |
|
|
91
|
-
| 79 | `lattice_brain/graph/discovery.py` | `name-defined` ×72, `attr-defined` ×7 |
|
|
92
|
-
| 107 | `lattice_brain/graph/retrieval_vector.py` | `name-defined` ×68, `attr-defined` ×39 |
|
|
93
|
-
| 108 | `latticeai/api/workspace.py` | `misc` ×105, `arg-type` ×2, `call-overload` ×1 |
|
|
94
|
-
| 127 | `lattice_brain/graph/discovery_index.py` | `name-defined` ×98, `attr-defined` ×29 |
|
|
95
|
-
| 143 | `lattice_brain/graph/projection.py` | `name-defined` ×122, `attr-defined` ×21 |
|
|
96
|
-
| 177 | `lattice_brain/graph/ingest.py` | `name-defined` ×122, `attr-defined` ×55 |
|
|
15
|
+
## Two root causes were 68% of the backlog
|
|
97
16
|
|
|
98
|
-
|
|
17
|
+
**`_kg_common.__all__` was computed** (`[name for name in globals() if not
|
|
18
|
+
name.startswith("__")]`). Correct at runtime, opaque to a checker: mypy could
|
|
19
|
+
not resolve a single name behind `from ._kg_common import *`, so twelve graph
|
|
20
|
+
modules reported **~750 false `name-defined` errors** and stayed unchecked.
|
|
21
|
+
Freezing the list to a literal fixed all of them.
|
|
22
|
+
`tests/unit/test_kg_common_exports.py` asserts the literal still equals what
|
|
23
|
+
the expression would produce, so it cannot drift.
|
|
24
|
+
|
|
25
|
+
**The eleven graph mixins had an unwritten contract.** `ingest` calls
|
|
26
|
+
`_upsert_node` from `write_master`, which calls `_v2_project_node` from
|
|
27
|
+
`projection`, and everything calls `_connect` — 229 `attr-defined` errors,
|
|
28
|
+
because from a checker's position each mixin is a bare class calling methods it
|
|
29
|
+
does not have. `lattice_brain/graph/_kg_contract.py` writes that contract down:
|
|
30
|
+
23 declared members, typing-only (`_Core` is `object` at runtime, so the MRO is
|
|
31
|
+
unchanged), verified by `tests/unit/test_kg_contract.py`.
|
|
32
|
+
|
|
33
|
+
Neither was a typing problem. Both were *readability* problems that a reader
|
|
34
|
+
had to solve by grepping eleven files.
|
|
35
|
+
|
|
36
|
+
## Real defects the remaining work surfaced
|
|
37
|
+
|
|
38
|
+
| defect | module | why it mattered |
|
|
39
|
+
| --- | --- | --- |
|
|
40
|
+
| four lines duplicated after a `return` | `core/workspace_os.py` | dead since the merge that introduced it; `remove_member` looked like it did its work twice |
|
|
41
|
+
| `main` was never exported | `app_factory.py` | `python -m latticeai.server_app` raised `AttributeError` — the module entrypoint did not run |
|
|
42
|
+
| `str` shadowed a `dict` in a loop | `models/router.py` | the custom-cloud-model branch built ids from the wrong variable |
|
|
43
|
+
| `Optional` seam called unguarded | `lattice_brain/context.py` | an unconfigured retrieval port raised `TypeError` inside failure isolation instead of naming itself |
|
|
44
|
+
|
|
45
|
+
(10.3.0 found three more the same way: `self._path` inside an error handler,
|
|
46
|
+
`Iterable` used without importing it, and `.get` on a possible `None`.)
|
|
47
|
+
|
|
48
|
+
## Conventions the sweep settled on
|
|
49
|
+
|
|
50
|
+
* **JSON-shaped payloads are `Dict[str, Any]`, not `Dict[str, object]`.**
|
|
51
|
+
`object` forced a cast at every nested access without catching anything;
|
|
52
|
+
the value really is arbitrary JSON.
|
|
53
|
+
* **Optional dependencies are aliased, then re-exported as `Any`**
|
|
54
|
+
(`AsyncOpenAI`, `mx`, `vlm_load`, `pyautogui`), so "installed" and "absent"
|
|
55
|
+
have the same declared type and call sites keep their historical name.
|
|
56
|
+
* **Async generators in Protocols are declared with `def`, not `async def`.**
|
|
57
|
+
`async def … -> AsyncIterator[T]` says "a coroutine resolving to an
|
|
58
|
+
iterator", which no implementation does.
|
|
59
|
+
* **A router dependency it cannot run without is bound through
|
|
60
|
+
`AppContext.require("name")`** — an absent dependency names itself at router
|
|
61
|
+
construction instead of surfacing as `'NoneType' object is not callable`
|
|
62
|
+
inside a request handler.
|
|
63
|
+
* **A defensive `isinstance` check on a parameter means the annotation is
|
|
64
|
+
wrong.** Widen the parameter (`Any`, `Optional[str]`) rather than deleting
|
|
65
|
+
the guard: the guard is what the callers actually need.
|
package/docs/ONBOARDING.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Lattice AI Onboarding
|
|
2
2
|
|
|
3
|
-
Current release: **10.
|
|
3
|
+
Current release: **10.5.0 — Everyday Words**.
|
|
4
4
|
|
|
5
5
|
The first-run goal is a five-minute path from "I opened the app" to "my Brain
|
|
6
6
|
has a source, a question, and proof." This page is the product contract behind
|
package/docs/OPERATIONS.md
CHANGED
package/docs/PERMISSION_MODE.md
CHANGED
|
@@ -36,10 +36,21 @@ Env default: `LATTICEAI_PERMISSION_MODE=strict|trusted|bypass`.
|
|
|
36
36
|
|
|
37
37
|
## UI
|
|
38
38
|
|
|
39
|
-
`PermissionModePanel` renders in
|
|
40
|
-
settings tab
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
`PermissionModePanel` renders in **설정 → 혼자 해도 되는 일** (`SystemPage`
|
|
40
|
+
settings tab; the section was called 에이전트 자율성 before 10.5.0). The same
|
|
41
|
+
dial is reachable on the home screen through `BrainQuickControls`.
|
|
42
|
+
|
|
43
|
+
It still renders whatever modes the catalog `/api/permission-mode/catalog`
|
|
44
|
+
returns rather than a hardcoded list, so a mode added server-side appears with
|
|
45
|
+
no frontend change. Since 10.5.0 the *wording* is no longer taken from the
|
|
46
|
+
server for modes the app knows: `frontend/src/lib/permissionCopy.ts` maps mode
|
|
47
|
+
id → plain-language label and summary (`strict` → 먼저 물어보기, `trusted` →
|
|
48
|
+
웬만하면 알아서, `bypass` → 거의 다 알아서), and both surfaces read that one
|
|
49
|
+
module so the dial cannot be named two ways. The server's own localized label
|
|
50
|
+
is the fallback for an id the map does not know — renaming a mode server-side
|
|
51
|
+
therefore changes the UI only for ids the app has no copy for.
|
|
52
|
+
|
|
53
|
+
The apply button stays disabled until
|
|
43
54
|
|
|
44
55
|
* a *different* mode is selected, and
|
|
45
56
|
* for a mode whose catalog entry sets `requires_ack`, the risk acknowledgement
|
package/docs/SURFACE_PARITY.md
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
> **Status: reference**
|
|
4
4
|
> 도입: v9.9.4 (2026-07-25, 리뷰 Wave 1.4 "표면 패리티 체크리스트").
|
|
5
|
-
> 갱신: v9.9.7 — 표에 남아 있던 ✖ 갭을 **전부** 해소.
|
|
5
|
+
> 갱신: v9.9.7 — 표에 남아 있던 ✖ 갭을 **전부** 해소.
|
|
6
|
+
> 갱신: **v10.4.0 — 남아 있던 ◐(부분 제공)를 전부 해소.** 표에 ◐ 는 더 이상 없다.
|
|
6
7
|
> 목적: 각 표면(서피스)이 Brain 계약의 어디까지를 제공하는지 **정직하게** 기록한다.
|
|
7
8
|
> "앱마다 다른 Lattice"를 방지하는 기준표이며, 기능을 과장하지 않는다.
|
|
8
9
|
|
|
@@ -22,9 +23,9 @@
|
|
|
22
23
|
|
|
23
24
|
| 루프 순간 | Web `/app` | Desktop | VS Code | Browser | Telegram |
|
|
24
25
|
| --- | --- | --- | --- | --- | --- |
|
|
25
|
-
| 첫 저장 (Capture) | ✅ DnD·폴더·웹 수집, 품질 경고 | ✅ (웹과 동일) |
|
|
26
|
+
| 첫 저장 (Capture) | ✅ DnD·폴더·웹 수집, 품질 경고 | ✅ (웹과 동일) | ✅ `sendToLattice` 파일/선택 + `captureFolder` 폴더 수집 (v10.4.0) | ✅ 페이지 캡처 (단일 목적) | ✅ 메시지 + 문서/사진 업로드 수집 |
|
|
26
27
|
| 첫 회상 (Recall) | ✅ 하이브리드 검색 + grounding 배지 + 출처→청크 | ✅ (동일) | ✅ `askCurrentFile`/`askBrain` — 동일 `/chat` grounding 배지 | ✅ 팝업 질문 + 동일 grounding 배지 (v9.9.7) | ✅ 답변 + grounding 배지 (v9.9.7) |
|
|
27
|
-
| 첫 산출물 (Artifact) | ✅ artifacts[] 카드·미리보기·Brain 기억 칩 | ✅ (동일) |
|
|
28
|
+
| 첫 산출물 (Artifact) | ✅ artifacts[] 카드·미리보기·Brain 기억 칩 | ✅ (동일) | ✅ `createFile` + `showArtifacts` 카드(보정/검증 플래그 포함, v10.4.0) | — (의도: 브라우저에서 파일 쓰기 없음) | ✅ 파일 + artifacts[] 카드 요약 (v10.4.0) |
|
|
28
29
|
| 첫 보호 (Approval) | ✅ 승인 카드 + TTL 카운트다운 + 재시작 생존 | ✅ (동일) | ✅ List/Approve/Reject 커맨드 + 토큰 캐시 | ✅ 대기 건수 표시 (승인은 웹에서, v9.9.7) | ✅ 인라인 Done/Cancel + run_id/token 재개 |
|
|
29
30
|
|
|
30
31
|
## 기능 상세 × 표면
|
|
@@ -42,14 +43,14 @@
|
|
|
42
43
|
| Watch 상태 신호 (v9.9.4) | ✅ 홈 카드 | ✅ | — | — | — |
|
|
43
44
|
| Review Center (제안 승인/거절) | ✅ | ✅ | ✅ `ltcai.reviewCenter` (409 충돌 정직 보고) | — (의도: 승인은 웹/에디터/봇에서) | ✅ `/review` + 인라인 승인/거절 (v9.9.7) |
|
|
44
45
|
| 데모 코퍼스 First Value Loop | ✅ | ✅ | — | — | — |
|
|
45
|
-
| 모델 로드/추천 | ✅ | ✅ |
|
|
46
|
+
| 모델 로드/추천 | ✅ | ✅ | ✅ `loadModel` + 하드웨어 기반 추천·근거 (v10.4.0) | — (의도) | — (의도) |
|
|
46
47
|
| 코드 편집 보조 (edit/explain/refactor/tests) | — | — | ✅ | — | — |
|
|
47
48
|
|
|
48
49
|
## 규칙
|
|
49
50
|
|
|
50
51
|
1. **API 계약이 기준이다.** 모든 표면은 동일한 sidecar API를 소비한다. 표면별 전용 API를 만들지 않는다.
|
|
51
52
|
2. **◐/✖ 는 문서화된 상태로만 존재한다.** 새 기능을 Web에 추가할 때 이 표를 갱신하고, 다른 표면에 제공하지 않을 경우 "—(의도)" 인지 "✖(갭)" 인지 명시한다.
|
|
52
|
-
3. **✖ 갭은 릴리스 노트의 Honest Limitations 후보다.** v9.9.7
|
|
53
|
+
3. **✖ 갭은 릴리스 노트의 Honest Limitations 후보다.** v9.9.7 이후 표에 남은 ✖는 **없고**, v10.4.0 이후 ◐ 도 **없다**.
|
|
53
54
|
- 남은 "—"는 전부 **설계 경계**이며, 각 항목에 이유를 함께 적는다. 예: 브라우저 확장은 파일을 쓰지 않으므로 산출물 생성이 없고, 승인 *결정*은 서명된 토큰이 필요한 흐름이라 대기 건수만 보여 주고 승인은 웹/에디터/봇에서 한다.
|
|
54
55
|
- 경계를 새로 만들 때는 "왜 제공하지 않는가"를 이 문서에 남긴다. 이유 없는 "—"는 갭이지 경계가 아니다.
|
|
55
56
|
4. 릴리스마다 이 표를 검토한다 (release checklist의 docs 단계).
|
|
@@ -63,7 +64,7 @@
|
|
|
63
64
|
|
|
64
65
|
- **회상 배지**: `askCurrentFile` / `askBrain`은 웹과 동일한 `POST /chat` 응답의 `grounding` 판정을 그대로 읽는다. 판정이 없으면 "근거 있음"으로 승격하지 않고 `unknown`으로 보고한다 (`vscode-extension/surface.ts::groundingBadge`).
|
|
65
66
|
- **Review Center**: `ltcai.reviewCenter`는 웹과 같은 `/api/proposals` 표면을 쓴다. 승인은 검토한 내용 그대로 적용하고, 409(스테이징 이후 파일 변경)는 "아무것도 쓰지 않았다"고 정직하게 알린다.
|
|
66
|
-
- **스텝 요약**: `ltcai.runAgent`는 실행 후 `steps`/`created_files`/`explanation`을 출력 채널에 요약한다. 라이브 SSE 타임라인은
|
|
67
|
+
- **스텝 요약**: `ltcai.runAgent`는 실행 후 `steps`/`created_files`/`explanation`을 출력 채널에 요약한다. (라이브 SSE 타임라인은 v9.9.7의 `ltcai.runAgentLive`가 같은 `agent_step` 프레임으로 제공한다 — 이 메모는 v9.9.6 시점 기준이었다.)
|
|
67
68
|
- 파싱 계약은 `tests/vscode-extension.test.cjs`가 sidecar 페이로드 모양 그대로 검증한다.
|
|
68
69
|
|
|
69
70
|
## v9.9.7 — 남은 갭을 닫은 방법
|
|
@@ -81,3 +82,29 @@
|
|
|
81
82
|
- **Browser 확장**: 캡처 전용 경계를 넘어 `/chat` 질문과 `agent/approvals` 대기
|
|
82
83
|
건수를 보여 준다. **판정을 로컬에서 계산하지 않는다** — 판정이 없으면
|
|
83
84
|
"근거 확인 불가"이며 절대 "근거 있음"으로 승격하지 않는다.
|
|
85
|
+
|
|
86
|
+
## v10.4.0 — 마지막 ◐ 셋을 닫은 방법
|
|
87
|
+
|
|
88
|
+
세 갭 모두 **계약의 문제가 아니라 렌더링의 문제**였다. 사이드카는 이미 필요한
|
|
89
|
+
데이터를 내고 있었고, 에디터/봇이 그것을 버리고 있었다.
|
|
90
|
+
|
|
91
|
+
- **VS Code 폴더 수집** (`ltcai.captureFolder`): 웹 Capture 와 **같은**
|
|
92
|
+
`POST /api/ingestion/folder` 를 쓴다. 로컬 디스크를 읽으므로 승인 절차도
|
|
93
|
+
동일하다 — 토큰 없는 첫 호출은 `permission_required` 이고, 확장은 그것을
|
|
94
|
+
그대로 보여 준다(조용히 재시도하지 않는다). 백그라운드 job 으로 큐잉되며
|
|
95
|
+
진행 상황은 웹에서 본다.
|
|
96
|
+
- **VS Code 산출물 카드** (`ltcai.showArtifacts`): `/agent` 응답의
|
|
97
|
+
`artifacts[]` 를 그대로 읽는다. 결정적으로 **보정된(repaired) 스캐폴드와
|
|
98
|
+
깨끗한 모델 출력이 구분된다** — 이전에는 평평한 경로 목록이라 둘이 같아
|
|
99
|
+
보였다. 서버의 `valid=false` 판정을 확장이 성공으로 승격하지 않는다.
|
|
100
|
+
구형 사이드카(`created_files` 만 있는 응답)는 "세부 정보 없음"이라고
|
|
101
|
+
정직하게 말한다.
|
|
102
|
+
- **VS Code 모델 추천**: `GET /setup/scan` 의 `zero_config.recommend` 를
|
|
103
|
+
읽어 **이 기기에 왜 이 모델인지**를 근거와 함께 보여 준다. 스캔이 없으면
|
|
104
|
+
배너도 없다 — 이유를 지어내지 않는다.
|
|
105
|
+
- **Telegram 산출물 카드**: 같은 `artifacts[]` 플래그를 파일 전송 직전에
|
|
106
|
+
요약한다. 8개까지 나열하고 나머지는 `… +N` 으로 정직하게 줄인다.
|
|
107
|
+
|
|
108
|
+
계약 테스트: `tests/vscode-extension.test.cjs` (19), `tests/unit/test_telegram_security.py`.
|
|
109
|
+
전부 사이드카 페이로드 모양 그대로 검증하며, 확장/봇이 서버 판정을 재계산하지
|
|
110
|
+
않는지도 함께 고정한다.
|
package/docs/TRUST_MODEL.md
CHANGED
package/docs/WHY_LATTICE.md
CHANGED
package/docs/kg-schema.md
CHANGED