ltcai 5.0.0 → 5.1.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.
Files changed (37) hide show
  1. package/README.md +57 -43
  2. package/docs/CHANGELOG.md +61 -0
  3. package/docs/TRUST_MODEL.md +66 -0
  4. package/docs/WHY_LATTICE.md +54 -0
  5. package/frontend/src/App.tsx +1 -1
  6. package/frontend/src/components/primitives.tsx +1 -1
  7. package/frontend/src/i18n.ts +6 -4
  8. package/frontend/src/pages/System.tsx +1 -1
  9. package/lattice_brain/__init__.py +1 -1
  10. package/lattice_brain/portability.py +11 -7
  11. package/lattice_brain/runtime/multi_agent.py +1 -1
  12. package/latticeai/__init__.py +1 -1
  13. package/latticeai/api/chat.py +19 -11
  14. package/latticeai/api/models.py +6 -0
  15. package/latticeai/api/security_dashboard.py +3 -15
  16. package/latticeai/api/static_routes.py +16 -0
  17. package/latticeai/app_factory.py +114 -40
  18. package/latticeai/core/audit.py +3 -1
  19. package/latticeai/core/builtin_hooks.py +7 -9
  20. package/latticeai/core/logging_safety.py +5 -21
  21. package/latticeai/core/marketplace.py +1 -1
  22. package/latticeai/core/security.py +67 -9
  23. package/latticeai/core/workspace_os.py +1 -1
  24. package/package.json +2 -2
  25. package/scripts/clean_release_artifacts.mjs +16 -1
  26. package/scripts/com.pts.claudecode.discord.plist +31 -0
  27. package/scripts/pts-claudecode-discord-bridge.mjs +189 -0
  28. package/scripts/run_integration_tests.mjs +91 -0
  29. package/scripts/start-pts-claudecode-discord.sh +51 -0
  30. package/src-tauri/Cargo.lock +1 -1
  31. package/src-tauri/Cargo.toml +1 -1
  32. package/src-tauri/tauri.conf.json +3 -2
  33. package/static/app/asset-manifest.json +3 -3
  34. package/static/app/assets/{index-FR1UZkCD.js → index-DONOJfMn.js} +2 -2
  35. package/static/app/assets/index-DONOJfMn.js.map +1 -0
  36. package/static/app/index.html +1 -1
  37. package/static/app/assets/index-FR1UZkCD.js.map +0 -1
package/README.md CHANGED
@@ -7,24 +7,33 @@
7
7
  [![CI Status](https://github.com/TaeSooPark-PTS/LatticeAI/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/TaeSooPark-PTS/LatticeAI/actions/workflows/ci.yml)
8
8
  [![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
9
9
 
10
- **Lattice AI v5.0.0 is the local-first Living Brain multilingual foundation release.**
11
- It keeps the v4 Brain Core, StorageEngine, FastAPI localhost API, Tauri shell,
12
- backup, restore, model runtime, graph, and portability architecture intact while
13
- making the normal user surface easier for non-technical users: safer login,
14
- clearer model setup, one-click Memory/Topic/Relationship/Graph views, visible feedback when conversation becomes Brain memory, and Korean/English language choice across first-run and Brain screens. Admin logs, role
15
- permissions, security events, retention posture, and Brain operations remain in
16
- the separate Admin Console.
17
-
18
- The product opens by stating the core reason to exist: models will change, but
19
- the user's knowledge should not. It creates a private local profile, studies the
20
- computer, recommends a replaceable model voice, asks before install/download/load
21
- work, then lands in Brain Chat with starter prompts for durable decisions,
22
- projects, documents, and context. The Brain home now gives direct buttons for
23
- memory, topics, relationships, and the full graph, so the graph is still real
24
- and searchable without becoming the first screen or a separate dashboard.
10
+ **Your private AI memory layer. Keep your knowledge. Switch any model.**
11
+
12
+ **모델은 바꿔도, 지식은 남는 로컬 AI 브레인.**
13
+
14
+ Lattice AI is a local-first Digital Brain for your conversations, documents,
15
+ decisions, project history, relationships, and workflows. It is not a ChatGPT
16
+ clone, a model launcher, a graph database, or a note app. The model is the voice
17
+ you use today. The Brain is the durable asset you keep.
18
+
19
+ Use Lattice AI when you want to:
20
+
21
+ - remember project decisions across weeks or months and see the source later;
22
+ - preserve context when switching between local, cloud, or future models;
23
+ - connect documents, conversations, files, notes, and decisions into one Brain;
24
+ - export, backup, inspect, verify, and move the Brain as an encrypted
25
+ `.latticebrain` archive;
26
+ - avoid cloud lock-in and keep knowledge local by default;
27
+ - get an honest unavailable state instead of a fake answer when no model or
28
+ evidence is available.
29
+
30
+ By default, Lattice binds to localhost, stores the Brain on your machine, keeps
31
+ model downloads and cloud calls behind explicit consent, and separates normal
32
+ Brain use from the Admin Console. Korean and English UI copy share the same
33
+ underlying Brain, so language preference changes the interface, not your data.
25
34
 
26
35
  External package registries are owner-published and can lag behind this GitHub
27
- Release. Release uploads must use the exact v5.0.0 artifact filenames below.
36
+ Release. Release uploads must use the exact v5.1.0 artifact filenames below.
28
37
 
29
38
  ## Living Brain Flow
30
39
 
@@ -33,17 +42,17 @@ Release. Release uploads must use the exact v5.0.0 artifact filenames below.
33
42
  First launch opens to Login only. The local profile is the beginning of the
34
43
  Brain, not a dashboard, graph, or setup grid. The first screen frames Lattice as
35
44
  a durable knowledge home where models are replaceable and ownership stays with
36
- the user. v5.0.0 also prevents an email typo or wrong saved-user password from
45
+ the user. v5.1.0 also prevents an email typo or wrong saved-user password from
37
46
  silently creating a new empty Brain.
38
47
 
39
- ![Login](output/release/v5.0.0/screenshots/01-login.png)
48
+ ![Login](output/release/v5.1.0/screenshots/01-login.png)
40
49
 
41
50
  ### 2. Environment Analysis
42
51
 
43
52
  Lattice reads the machine locally and summarizes what kind of Brain this
44
53
  computer can support.
45
54
 
46
- ![Environment Analysis](output/release/v5.0.0/screenshots/02-environment-analysis.png)
55
+ ![Environment Analysis](output/release/v5.1.0/screenshots/02-environment-analysis.png)
47
56
 
48
57
  ### 3. Recommended Models
49
58
 
@@ -51,7 +60,7 @@ The model step is a short recommendation list. It avoids catalog noise and keeps
51
60
  runtime/install details behind clear user consent. Users who do not know which
52
61
  model to choose can start with the recommended model in one click.
53
62
 
54
- ![Recommended Models](output/release/v5.0.0/screenshots/03-recommended-models.png)
63
+ ![Recommended Models](output/release/v5.1.0/screenshots/03-recommended-models.png)
55
64
 
56
65
  ### 4. Install And Load
57
66
 
@@ -60,7 +69,7 @@ and load progress. No model download or runtime install starts silently, and the
60
69
  screen explains that large downloads may take minutes without inventing fake ETA
61
70
  data.
62
71
 
63
- ![Install and Load](output/release/v5.0.0/screenshots/04-install-load-progress.png)
72
+ ![Install and Load](output/release/v5.1.0/screenshots/04-install-load-progress.png)
64
73
 
65
74
  ### 5. Brain Chat
66
75
 
@@ -69,7 +78,7 @@ stays present while the user types, recalls context, and receives responses. The
69
78
  home now includes a compact Brain overview for recent memories, older memories,
70
79
  and major topics, plus saved-to-memory feedback after chat.
71
80
 
72
- ![Brain Chat Home](output/release/v5.0.0/screenshots/05-brain-chat-home.png)
81
+ ![Brain Chat Home](output/release/v5.1.0/screenshots/05-brain-chat-home.png)
73
82
 
74
83
  ## Brain Depths
75
84
 
@@ -78,26 +87,26 @@ while revealing more structure.
78
87
 
79
88
  | Depth | Experience | Evidence |
80
89
  | --- | --- | --- |
81
- | Level 1 | Living Brain presence | ![Living Brain Level 1](output/release/v5.0.0/screenshots/06-living-brain-level-1.png) |
82
- | Level 2 | Memory Layer | ![Memory Layer](output/release/v5.0.0/screenshots/07-memory-layer.png) |
83
- | Level 3 | Knowledge Layer | ![Knowledge Layer](output/release/v5.0.0/screenshots/08-knowledge-layer.png) |
84
- | Level 4 | Relationship Layer | ![Relationship Layer](output/release/v5.0.0/screenshots/09-relationship-layer.png) |
85
- | Level 5 | Knowledge Graph with nodes, edges, search, and focus detail | ![Knowledge Graph Layer](output/release/v5.0.0/screenshots/10-knowledge-graph-layer.png) |
90
+ | Level 1 | Living Brain presence | ![Living Brain Level 1](output/release/v5.1.0/screenshots/06-living-brain-level-1.png) |
91
+ | Level 2 | Memory Layer | ![Memory Layer](output/release/v5.1.0/screenshots/07-memory-layer.png) |
92
+ | Level 3 | Knowledge Layer | ![Knowledge Layer](output/release/v5.1.0/screenshots/08-knowledge-layer.png) |
93
+ | Level 4 | Relationship Layer | ![Relationship Layer](output/release/v5.1.0/screenshots/09-relationship-layer.png) |
94
+ | Level 5 | Knowledge Graph with nodes, edges, search, and focus detail | ![Knowledge Graph Layer](output/release/v5.1.0/screenshots/10-knowledge-graph-layer.png) |
86
95
 
87
96
  Walkthrough:
88
97
 
89
- ![v5.0.0 Living Brain walkthrough](output/release/v5.0.0/gifs/v5.0.0-living-brain-walkthrough.gif)
98
+ ![v5.1.0 Living Brain walkthrough](output/release/v5.1.0/gifs/v5.1.0-living-brain-walkthrough.gif)
90
99
 
91
100
  Model setup status evidence:
92
101
 
93
- ![Model setup status](output/release/v5.0.0/screenshots/11-model-setup-status.png)
102
+ ![Model setup status](output/release/v5.1.0/screenshots/11-model-setup-status.png)
94
103
 
95
104
  Separate admin console evidence:
96
105
 
97
- ![Admin Console](output/release/v5.0.0/screenshots/12-admin-console.png)
106
+ ![Admin Console](output/release/v5.1.0/screenshots/12-admin-console.png)
98
107
 
99
108
  Screenshot index and capture notes:
100
- [output/release/v5.0.0/SCREENSHOT_INDEX.md](output/release/v5.0.0/SCREENSHOT_INDEX.md)
109
+ [output/release/v5.1.0/SCREENSHOT_INDEX.md](output/release/v5.1.0/SCREENSHOT_INDEX.md)
101
110
 
102
111
  ## Architecture At A Glance
103
112
 
@@ -127,7 +136,7 @@ Screenshot index and capture notes:
127
136
  rebuild controls live under the separate `#/admin` console. Admin history,
128
137
  audit, stats, and sensitivity reads honor the active workspace when present.
129
138
 
130
- See [ARCHITECTURE.md](ARCHITECTURE.md) for the detailed v5.0.0 architecture.
139
+ See [ARCHITECTURE.md](ARCHITECTURE.md) for the detailed v5.1.0 architecture.
131
140
 
132
141
  ## Installation
133
142
 
@@ -159,13 +168,13 @@ pip install "ltcai[local]"
159
168
 
160
169
  ## Release Artifacts
161
170
 
162
- Validated v5.0.0 artifacts:
171
+ Validated v5.1.0 artifacts:
163
172
 
164
- - `dist/ltcai-5.0.0-py3-none-any.whl`
165
- - `dist/ltcai-5.0.0.tar.gz`
166
- - `ltcai-5.0.0.tgz`
167
- - `dist/ltcai-5.0.0.vsix`
168
- - `src-tauri/target/release/bundle/dmg/Lattice AI_5.0.0_aarch64.dmg`
173
+ - `dist/ltcai-5.1.0-py3-none-any.whl`
174
+ - `dist/ltcai-5.1.0.tar.gz`
175
+ - `ltcai-5.1.0.tgz`
176
+ - `dist/ltcai-5.1.0.vsix`
177
+ - `src-tauri/target/release/bundle/dmg/Lattice AI_5.1.0_aarch64.dmg`
169
178
 
170
179
  Attach only those exact files to the GitHub Release. Do not upload `dist/*`.
171
180
 
@@ -194,7 +203,7 @@ npm run test:unit
194
203
  npm run test:integration
195
204
  npm run test:visual
196
205
  npm run desktop:tauri:check
197
- node scripts/run_python.mjs scripts/wheel_smoke.py --wheel dist/ltcai-5.0.0-py3-none-any.whl
206
+ node scripts/run_python.mjs scripts/wheel_smoke.py --wheel dist/ltcai-5.1.0-py3-none-any.whl
198
207
  npm pack --dry-run
199
208
  npm run docs:check-links
200
209
  ```
@@ -210,13 +219,14 @@ npm run docs:check-links
210
219
  - Agent/workflow simulation without a loaded LLM is deterministic and does not call a model.
211
220
  It is labeled as LLM-free/model-free rather than presented as autonomous model
212
221
  success.
213
- - Historical artifacts can remain in `dist/`; uploads must use exact v5.0.0
222
+ - Historical artifacts can remain in `dist/`; uploads must use exact v5.1.0
214
223
  filenames.
215
224
 
216
225
  ## Release History
217
226
 
218
227
  | Version | Theme |
219
228
  | --- | --- |
229
+ | 5.1.0 | Product Trust & Clarity Release: clarifies the private AI memory-layer promise, hardens CSP/secret/auto-read/download gates, adds trust/privacy docs, and refreshes v5.1.0 evidence |
220
230
  | 5.0.0 | Multilingual Brain Foundation Release: adds persisted Korean/English language choice across first-run onboarding, Brain home, graph exploration, and Admin Console while preserving the v4 runtime foundations |
221
231
  | 4.7.2 | Intuitive Brain UX Release: safer login, one-click recommended setup, direct Brain views, memory-save feedback, and exact v4.7.2 artifacts |
222
232
  | 4.7.0 | Admin Separation Release: added the separate Admin Console for users/logs/security/Brain operations, refreshed screenshots/GIFs, synchronized release docs, and built exact v4.7.0 artifacts |
@@ -237,19 +247,23 @@ npm run docs:check-links
237
247
 
238
248
  ## Current Documentation
239
249
 
240
- - [ARCHITECTURE.md](ARCHITECTURE.md) - v5.0.0 architecture.
250
+ - [ARCHITECTURE.md](ARCHITECTURE.md) - v5.1.0 architecture.
251
+ - [docs/WHY_LATTICE.md](docs/WHY_LATTICE.md) - why Lattice AI exists.
252
+ - [docs/TRUST_MODEL.md](docs/TRUST_MODEL.md) - local-first trust model.
253
+ - [PRIVACY.md](PRIVACY.md) - privacy and external communication policy.
241
254
  - [docs/PRODUCT_DIRECTION_REVIEW.md](docs/PRODUCT_DIRECTION_REVIEW.md) -
242
255
  Brain-first product direction review.
243
256
  - [FEATURE_STATUS.md](FEATURE_STATUS.md) - current feature status and historical
244
257
  status ledger.
245
258
  - [RELEASE_NOTES.md](RELEASE_NOTES.md) - release notes index.
246
- - [RELEASE_NOTES_v5.0.0.md](RELEASE_NOTES_v5.0.0.md) - v5.0.0 intuitive Brain UX release notes.
259
+ - [RELEASE_NOTES_v5.1.0.md](RELEASE_NOTES_v5.1.0.md) - v5.1.0 Product Trust & Clarity release notes.
260
+ - [RELEASE_NOTES_v5.0.0.md](RELEASE_NOTES_v5.0.0.md) - v5.0.0 multilingual foundation history.
247
261
  - [RELEASE_NOTES_v4.6.1.md](RELEASE_NOTES_v4.6.1.md) - v4.6.1 release refresh history.
248
262
  - [RELEASE_NOTES_v4.6.0.md](RELEASE_NOTES_v4.6.0.md) - v4.6.0 Living Brain history.
249
263
  - [RELEASE.md](RELEASE.md) - release checklist and exact artifact guidance.
250
264
  - [SECURITY.md](SECURITY.md) - security posture.
251
265
  - [docs/CHANGELOG.md](docs/CHANGELOG.md) - changelog.
252
- - [docs/V4_7_1_ADMIN_OPERATIONS_REPORT.md](docs/V4_7_1_ADMIN_OPERATIONS_REPORT.md) - v5.0.0 admin operations report.
266
+ - [docs/V4_7_1_ADMIN_OPERATIONS_REPORT.md](docs/V4_7_1_ADMIN_OPERATIONS_REPORT.md) - v4.7.1 admin operations history.
253
267
  - [docs/V4_7_0_ADMIN_SEPARATION_REPORT.md](docs/V4_7_0_ADMIN_SEPARATION_REPORT.md) - v4.7.0 admin separation history.
254
268
  - [docs/V4_6_1_RELEASE_REFRESH_REPORT.md](docs/V4_6_1_RELEASE_REFRESH_REPORT.md) - v4.6.1 release refresh report.
255
269
  - [docs/V4_6_0_LIVING_BRAIN_EXPERIENCE_REPORT.md](docs/V4_6_0_LIVING_BRAIN_EXPERIENCE_REPORT.md) - v4.6.0 Living Brain design notes.
package/docs/CHANGELOG.md CHANGED
@@ -3,6 +3,67 @@
3
3
  The top entry is the current release-preparation target. Older entries are
4
4
  historical and may describe behavior as it existed at that release.
5
5
 
6
+ ## [5.1.0] - 2026-06-14
7
+
8
+ > Product Trust & Clarity Release. v5.1.0 clarifies Lattice AI as a
9
+ > local-first private AI memory layer / Digital Brain, then adds security,
10
+ > privacy, honesty, and architecture gates so the product does not overclaim.
11
+
12
+ ### Changed
13
+
14
+ - Rewrote the README first screen around the positioning lines
15
+ `Your private AI memory layer. Keep your knowledge. Switch any model.` and
16
+ `모델은 바꿔도, 내 지식은 남는 로컬 AI 브레인.`
17
+ - Added practical use cases for preserving project decisions, switching models,
18
+ connecting documents/conversations/files/notes/decisions, encrypted Brain
19
+ archive portability, cloud lock-in avoidance, and honest no-model states.
20
+ - Added and refreshed trust documentation: `PRIVACY.md`, `docs/WHY_LATTICE.md`,
21
+ `docs/TRUST_MODEL.md`, `SECURITY.md`, `ARCHITECTURE.md`, and
22
+ `FEATURE_STATUS.md`.
23
+ - Removed `csp:null` from Tauri production config and added an app-shell CSP
24
+ response header.
25
+ - Centralized secret redaction for logs, audit payloads, security exports, and
26
+ builtin hook packets.
27
+ - Changed chat auto-file handling so `LATTICEAI_AUTO_READ_CHAT_PATHS` remains
28
+ off by default and does not silently read arbitrary local paths even if
29
+ enabled.
30
+ - Added explicit `allow_download=true` consent for model download requests.
31
+ - Added config, security, and Brain runtime builder seams in `app_factory.py`
32
+ while preserving the existing API shape.
33
+ - Hardened release artifact cleanup so `release:artifacts` removes stale
34
+ `dist/ltcai-*` and root `ltcai-*.tgz` files before rebuilding exact v5.1.0
35
+ artifacts only.
36
+ - Made `npm run test:integration` self-contained by starting a local uvicorn
37
+ server, waiting for `/health`, running the integration suite, and shutting the
38
+ server down.
39
+ - Fixed a SQLite Brain restore TOCTOU race where transient `-wal` / `-shm`
40
+ siblings could disappear between probe and copy during archive restore.
41
+ - Bumped synchronized package/runtime/static versions to `5.1.0`, including
42
+ Python metadata, npm package metadata, VSIX metadata, Tauri metadata,
43
+ `latticeai`, `lattice_brain`, runtime constants, and static asset metadata.
44
+
45
+ ### Added
46
+
47
+ - v5.1 trust validation tests for CSP, secret redaction, audit redaction,
48
+ auto-file-read blocking, public/network auth posture, `shell=True`
49
+ production-path scanning, and Brain Core import isolation.
50
+ - A deterministic regression test for restore-time WAL sibling disappearance.
51
+ - v5.1 release evidence paths under `output/release/v5.1.0`.
52
+
53
+ ### Preserved
54
+
55
+ - v5.0.0 and older sections remain historical.
56
+ - External package publishing remains owner-run; this release prepares exact
57
+ artifacts and GitHub Release assets without registry publish automation.
58
+
59
+ ### Artifacts
60
+
61
+ - `dist/ltcai-5.1.0-py3-none-any.whl`
62
+ - `dist/ltcai-5.1.0.tar.gz`
63
+ - `dist/ltcai-5.1.0.vsix`
64
+ - `ltcai-5.1.0.tgz`
65
+ - `src-tauri/target/release/bundle/dmg/Lattice AI_5.1.0_aarch64.dmg`
66
+
6
67
  ## [5.0.0] - 2026-06-14
7
68
 
8
69
  > Multilingual Brain Foundation Release. v5.0.0 starts the major-version cleanup
@@ -0,0 +1,66 @@
1
+ # Lattice AI Trust Model
2
+
3
+ Lattice AI's trust model is local-first, opt-in for external communication, and
4
+ honest when something is unavailable.
5
+
6
+ ## Local By Default
7
+
8
+ By default, Lattice AI binds the API to `127.0.0.1`, stores Brain data under the
9
+ local data directory, and does not send prompts, documents, graph content, or
10
+ archives to Lattice-owned servers.
11
+
12
+ Local data includes:
13
+
14
+ - local profile and sessions;
15
+ - conversations and memory records;
16
+ - Knowledge Graph nodes, edges, provenance, and search indexes;
17
+ - uploaded document blobs;
18
+ - audit and admin operation logs;
19
+ - backups and encrypted `.latticebrain` archives.
20
+
21
+ ## Explicit External Paths
22
+
23
+ Some features can contact third parties, but they require explicit user/admin
24
+ action or configuration:
25
+
26
+ - model downloads from model registries;
27
+ - cloud model API calls after keys are configured and a cloud model is chosen;
28
+ - Telegram bridge after the integration is enabled;
29
+ - Brain Network peer actions after pairing/initiating network flows;
30
+ - Docker/Postgres setup after opt-in scale configuration;
31
+ - update checks only when update checking is enabled;
32
+ - remote marketplace/registry refreshes only through explicit user actions.
33
+
34
+ Token presence alone must not start external communication.
35
+
36
+ ## Consent And Honesty Gates
37
+
38
+ Lattice AI should fail closed or report unavailable state for:
39
+
40
+ - no model loaded;
41
+ - local model not installed;
42
+ - installed model not loaded;
43
+ - missing cloud key;
44
+ - deterministic/model-free preview;
45
+ - dry-run versus real execution;
46
+ - no graph/context evidence available;
47
+ - unavailable external integration;
48
+ - wrong archive passphrase;
49
+ - archive path traversal or tampering.
50
+
51
+ ## Admin Boundary
52
+
53
+ The normal user product is Brain Chat, memory, topics, relationships, graph
54
+ exploration, model state, and Brain ownership. Admin Console is for users,
55
+ roles, audit logs, security events, retention, and operations. Admin visibility
56
+ does not mean secrets should appear in clear text.
57
+
58
+ ## Known Limitations
59
+
60
+ - Local files are only as protected as the user's machine, account, backups, and
61
+ disk encryption.
62
+ - Cloud model prompts follow the selected provider's policy.
63
+ - A local admin can inspect local files and process memory outside Lattice AI.
64
+ - Marketplace and model registries are third-party services when explicitly
65
+ contacted.
66
+
@@ -0,0 +1,54 @@
1
+ # Why Lattice AI Exists
2
+
3
+ **Your private AI memory layer. Keep your knowledge. Switch any model.**
4
+
5
+ **모델은 바꿔도, 내 지식은 남는 로컬 AI 브레인.**
6
+
7
+ AI models change quickly. A model you use today may be replaced next month, and
8
+ the conversation history, project context, decisions, and sources you built
9
+ around it can become scattered across tools. Lattice AI exists so the durable
10
+ asset is not the model. The durable asset is your Brain.
11
+
12
+ ## The Problem
13
+
14
+ Most AI products begin with a model and treat your context as temporary prompt
15
+ material. That works for short questions, but it fails for long-running work:
16
+
17
+ - project decisions disappear into old chats;
18
+ - documents and notes are disconnected from conversations;
19
+ - switching models often means losing useful context;
20
+ - graph or database tools expose implementation details before user value;
21
+ - cloud-only products make it hard to inspect, back up, or move your knowledge.
22
+
23
+ ## The Lattice Answer
24
+
25
+ Lattice AI is a local-first private AI memory layer. It keeps conversations,
26
+ documents, decisions, relationships, and project history in a Brain that belongs
27
+ to the user. Models can be local, cloud, current, or future. The Brain remains.
28
+
29
+ The graph is real, but it is not the product identity. Users start with Brain
30
+ Chat, memory, topics, relationships, ownership, backup, and graph exploration.
31
+ Advanced admin logs, roles, hooks, workflows, Telegram, Brain Network, Docker,
32
+ Postgres, and plugin details stay outside the normal user flow.
33
+
34
+ ## Practical Reasons To Use It
35
+
36
+ - Ask what the team decided last week and see the source.
37
+ - Drop in documents and build a searchable personal memory.
38
+ - Prepare for a meeting from past notes, project decisions, and files.
39
+ - Preserve context when moving from one model to another.
40
+ - Export or back up the Brain as an encrypted `.latticebrain` archive.
41
+ - Use Korean or English without changing the underlying Brain.
42
+ - Avoid fake answers when no model or evidence is available.
43
+
44
+ ## What Lattice AI Is Not
45
+
46
+ - Not a hosted SaaS by default.
47
+ - Not just a model launcher.
48
+ - Not just a graph viewer.
49
+ - Not a generic dashboard.
50
+ - Not a note-taking clone.
51
+ - Not a ChatGPT or Claude clone.
52
+
53
+ Lattice AI is for people who want their knowledge to survive model changes.
54
+
@@ -245,7 +245,7 @@ function BrainHome({
245
245
  if (result.error) {
246
246
  setMessages((items) => {
247
247
  const next = [...items];
248
- next[next.length - 1] = { role: "assistant", content: `Unavailable: ${result.error}` };
248
+ next[next.length - 1] = { role: "assistant", content: `${t(language, "brain.unavailable")}: ${result.error}` };
249
249
  return next;
250
250
  });
251
251
  } else {
@@ -316,7 +316,7 @@ export function ModeGate({
316
316
  <div className="text-lg font-semibold">{title}</div>
317
317
  <p className="mt-1 max-w-2xl text-sm leading-6 text-muted-foreground">{detail}</p>
318
318
  </div>
319
- <Button onClick={() => setMode(target)}>{target === "admin" ? "Switch to Admin" : "Switch to Advanced"}</Button>
319
+ <Button onClick={() => setMode(target)}>{target === "admin" ? "Switch to Admin Console" : "Switch to Advanced"}</Button>
320
320
  </CardContent>
321
321
  </Card>
322
322
  );
@@ -27,7 +27,7 @@ export const COPY: Record<Language, TextMap> = {
27
27
  "brain.local": "로컬 우선",
28
28
  "brain.portable": "이동 가능",
29
29
  "brain.private": "개인 소유",
30
- "brain.admin": "관리자",
30
+ "brain.admin": "관리자 콘솔",
31
31
  "brain.empty.kicker": "내 오래가는 기억",
32
32
  "brain.empty.title": "잊으면 안 되는 일부터 말해 주세요.",
33
33
  "brain.empty.body": "문서, 대화, 프로젝트, 결정이 Brain에 쌓이고 나중에 주제와 관계로 다시 보입니다.",
@@ -36,6 +36,7 @@ export const COPY: Record<Language, TextMap> = {
36
36
  "brain.prompt.plan": "이 프로젝트 맥락을 계획으로 바꿔줘: ",
37
37
  "brain.placeholder": "Brain에게 말하기...",
38
38
  "brain.image": "이미지",
39
+ "brain.unavailable": "지금은 답할 수 없음",
39
40
  "brain.imageAttached": "이미지 첨부됨",
40
41
  "brain.send": "보내기",
41
42
  "brain.saved": "기억에 저장됨 · 연결된 주제 {topics}개 · 관련 기억 {memories}개",
@@ -74,7 +75,7 @@ export const COPY: Record<Language, TextMap> = {
74
75
  "admin.kicker": "분리된 관리자 작업공간",
75
76
  "admin.title": "Admin Console",
76
77
  "admin.body": "사용자, 로그, 보안, Brain 상태는 일반 사용자 화면과 분리됩니다.",
77
- "flow.shell": "내 Brain 깨우기",
78
+ "flow.shell": "내 로컬 Brain 만들기",
78
79
  "flow.login.title": "내 Brain을 시작합니다.",
79
80
  "flow.login.body": "모델은 바뀔 수 있지만, 내 문서와 대화, 결정, 기억은 사라지면 안 됩니다. Lattice는 이 지식을 내가 소유하는 개인 Brain으로 모읍니다.",
80
81
  "flow.name": "이름",
@@ -139,7 +140,7 @@ export const COPY: Record<Language, TextMap> = {
139
140
  "brain.local": "Local-first",
140
141
  "brain.portable": "Portable",
141
142
  "brain.private": "Private",
142
- "brain.admin": "Admin",
143
+ "brain.admin": "Admin Console",
143
144
  "brain.empty.kicker": "Durable memory",
144
145
  "brain.empty.title": "Start with what should not be forgotten.",
145
146
  "brain.empty.body": "Documents, conversations, projects, and decisions accumulate in your Brain, then reappear as topics and relationships.",
@@ -148,6 +149,7 @@ export const COPY: Record<Language, TextMap> = {
148
149
  "brain.prompt.plan": "Turn this project context into a plan: ",
149
150
  "brain.placeholder": "Talk to your Brain...",
150
151
  "brain.image": "Image",
152
+ "brain.unavailable": "Unavailable",
151
153
  "brain.imageAttached": "Image attached",
152
154
  "brain.send": "Send",
153
155
  "brain.saved": "Saved to memory · {topics} linked topics · {memories} related memories",
@@ -186,7 +188,7 @@ export const COPY: Record<Language, TextMap> = {
186
188
  "admin.kicker": "Separate admin workspace",
187
189
  "admin.title": "Admin Console",
188
190
  "admin.body": "Users, logs, security, and Brain health stay out of the normal user experience.",
189
- "flow.shell": "Awaken your Brain",
191
+ "flow.shell": "Create your local Brain",
190
192
  "flow.login.title": "Start your Brain.",
191
193
  "flow.login.body": "Models can change, but your documents, conversations, decisions, and memories should stay yours. Lattice gathers them into a personal Brain you control.",
192
194
  "flow.name": "Name",
@@ -19,7 +19,7 @@ const tabs: Array<{ id: SystemTab; label: string }> = [
19
19
  { id: "activity", label: "History" },
20
20
  { id: "network", label: "Devices" },
21
21
  { id: "settings", label: "Preferences" },
22
- { id: "admin", label: "Admin" },
22
+ { id: "admin", label: "Admin Console" },
23
23
  ];
24
24
 
25
25
  export function SystemPage({ initialTab }: { initialTab?: string }) {
@@ -26,7 +26,7 @@ from .storage import (
26
26
  storage_from_env,
27
27
  )
28
28
 
29
- __version__ = "5.0.0"
29
+ __version__ = "5.1.0"
30
30
 
31
31
  __all__ = [
32
32
  "AgentRuntime",
@@ -75,8 +75,8 @@ def _sqlite_siblings(db_path: Path) -> tuple[Path, Path, Path]:
75
75
  def _restore_sibling(path: Path, backup: Path) -> None:
76
76
  if backup.exists():
77
77
  shutil.copy2(backup, path)
78
- elif path.exists():
79
- path.unlink()
78
+ else:
79
+ path.unlink(missing_ok=True)
80
80
 
81
81
 
82
82
  def _replace_sqlite_atomically(src: Path, dest: Path, backup_dir: Path) -> None:
@@ -85,14 +85,18 @@ def _replace_sqlite_atomically(src: Path, dest: Path, backup_dir: Path) -> None:
85
85
  shutil.copyfile(src, tmp)
86
86
  backups: dict[Path, Path] = {}
87
87
  try:
88
+ # -wal/-shm are transient: another live connection can checkpoint and
89
+ # remove them between exists() and the copy/unlink. Treat a vanished
90
+ # sibling as "nothing to preserve" instead of crashing the restore.
88
91
  for sibling in _sqlite_siblings(dest):
89
- if sibling.exists():
90
- backup = backup_dir / sibling.name
92
+ backup = backup_dir / sibling.name
93
+ try:
91
94
  shutil.copy2(sibling, backup)
92
- backups[sibling] = backup
95
+ except FileNotFoundError:
96
+ continue
97
+ backups[sibling] = backup
93
98
  for sibling in _sqlite_siblings(dest)[1:]:
94
- if sibling.exists():
95
- sibling.unlink()
99
+ sibling.unlink(missing_ok=True)
96
100
  os.replace(tmp, dest)
97
101
  except Exception:
98
102
  if tmp.exists():
@@ -14,7 +14,7 @@ from datetime import datetime
14
14
  from typing import Any, Callable, Dict, List, Optional
15
15
 
16
16
 
17
- MULTI_AGENT_VERSION = "5.0.0"
17
+ MULTI_AGENT_VERSION = "5.1.0"
18
18
 
19
19
  AGENT_ROLES = ("researcher", "planner", "executor", "reviewer", "release")
20
20
  CORE_PIPELINE = ("planner", "executor", "reviewer")
@@ -1,3 +1,3 @@
1
1
  """Lattice AI - modular server package."""
2
2
 
3
- __version__ = "5.0.0"
3
+ __version__ = "5.1.0"
@@ -27,7 +27,7 @@ from latticeai.core.document_generator import DocumentGenerationSession, detect_
27
27
  from lattice_brain.runtime.hooks import dispatch_tool
28
28
  from latticeai.services.app_context import AppContext
29
29
  from latticeai.services.tool_dispatch import build_agent_runtime, collect_created_files
30
- from tools import AGENT_ROOT, ToolError, ensure_agent_root, execute_tool, knowledge_save, local_read, network_status
30
+ from tools import AGENT_ROOT, ToolError, ensure_agent_root, execute_tool, knowledge_save, network_status
31
31
 
32
32
  class ChatRequest(BaseModel):
33
33
  message: str
@@ -42,6 +42,7 @@ class ChatRequest(BaseModel):
42
42
  user_email: Optional[str] = None
43
43
  user_nickname: Optional[str] = None
44
44
  image_data: Optional[str] = None
45
+ allow_file_context: bool = False
45
46
 
46
47
 
47
48
  class AgentRequest(BaseModel):
@@ -450,16 +451,23 @@ def create_chat_router(context: AppContext) -> APIRouter:
450
451
 
451
452
  if CONFIG.auto_read_chat_paths:
452
453
  _file_path_re = re.compile(r'(?:^|[\s\'\"(])((~|/[\w.])[^\s\'")\]]*)', re.MULTILINE)
453
- for _m in _file_path_re.finditer(req.message or ""):
454
- _fpath = _m.group(1).strip()
455
- try:
456
- _result = local_read(_fpath)
457
- _fcontent = _result.get("content", "")
458
- if _fcontent:
459
- context += f"\n\n[FILE: {_fpath}]\n```\n{_fcontent[:6000]}\n```"
460
- print(f"📂 Auto-injected file context: {_fpath}")
461
- except Exception:
462
- pass
454
+ requested_paths = [_m.group(1).strip() for _m in _file_path_re.finditer(req.message or "")]
455
+ if requested_paths:
456
+ append_audit_event(
457
+ "auto_file_context_blocked",
458
+ user_email=effective_email,
459
+ path_count=len(requested_paths),
460
+ allow_file_context=req.allow_file_context,
461
+ reason="local file context requires an explicit approved file/tool flow",
462
+ )
463
+ if req.allow_file_context:
464
+ raise HTTPException(
465
+ status_code=400,
466
+ detail=(
467
+ "Automatic local file reads are disabled in chat. "
468
+ "Attach the file, upload it, or use an approved local-file tool flow."
469
+ ),
470
+ )
463
471
 
464
472
  trace_seed = CHAT_SERVICE.build_graph_trace(
465
473
  req.message,
@@ -77,6 +77,7 @@ class SetApiKeyRequest(BaseModel):
77
77
 
78
78
  class PullModelRequest(BaseModel):
79
79
  model: str
80
+ allow_download: bool = False
80
81
 
81
82
 
82
83
  class PrepareModelRequest(BaseModel):
@@ -291,6 +292,11 @@ def create_models_router(
291
292
  @router.post("/engines/pull-model")
292
293
  async def pull_ollama_model(req: PullModelRequest, request: Request):
293
294
  require_user(request)
295
+ if not req.allow_download:
296
+ raise HTTPException(
297
+ status_code=403,
298
+ detail="Model downloads require explicit user consent (allow_download=true).",
299
+ )
294
300
  model_ref = normalize_local_model_request(req.model, None)
295
301
  if not model_ref:
296
302
  raise HTTPException(status_code=400, detail="모델 식별자가 비어 있습니다.")