ltcai 11.7.0 → 12.0.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 +100 -76
- package/docs/BENCHMARKS.md +9 -2
- package/docs/CHANGELOG.md +249 -0
- package/docs/CI_AND_RELEASE_GATES.md +126 -41
- package/docs/COMMUNITY_AND_PLUGINS.md +1 -1
- package/docs/DEVELOPMENT.md +271 -103
- package/docs/ENTERPRISE.md +1 -1
- package/docs/LEGACY_COMPATIBILITY.md +10 -6
- package/docs/MULTI_AGENT_RUNTIME.md +4 -4
- package/docs/ONBOARDING.md +16 -4
- package/docs/OPERATIONS.md +14 -1
- package/docs/PERMISSION_MODE.md +14 -9
- package/docs/REALTIME_COLLABORATION.md +1 -1
- package/docs/ROADMAP.md +113 -0
- package/docs/TRUST_MODEL.md +28 -7
- package/docs/USABILITY_AUDIT.md +5 -0
- package/docs/WHY_LATTICE.md +13 -5
- package/docs/WORKFLOW_DESIGNER.md +2 -2
- package/docs/kg-schema.md +57 -7
- package/docs/mcp-tools.md +93 -82
- package/docs/security-model.md +6 -3
- package/lattice_brain/__init__.py +1 -1
- package/lattice_brain/graph/_kg_common/__init__.py +1 -54
- package/lattice_brain/graph/_kg_common/extraction.py +459 -105
- package/lattice_brain/graph/_kg_common/normalize.py +305 -0
- package/lattice_brain/graph/_kg_common/patterns.py +275 -0
- package/lattice_brain/graph/_kg_common/relations.py +12 -3
- package/lattice_brain/graph/_kg_common/sections.py +107 -0
- package/lattice_brain/graph/_kg_common/text.py +14 -450
- package/lattice_brain/graph/_kg_constants.py +7 -0
- package/lattice_brain/ingestion/__init__.py +6 -3
- package/lattice_brain/multimodal/__init__.py +9 -3
- package/latticeai/__init__.py +1 -1
- package/latticeai/api/agent_worker_seam.py +44 -1
- package/latticeai/api/models.py +18 -110
- package/latticeai/api/search.py +7 -30
- package/latticeai/api/worker_compute.py +127 -106
- package/latticeai/api/worker_seams.py +17 -2
- package/latticeai/core/embedding_providers/__init__.py +16 -0
- package/latticeai/core/embedding_providers/autodetect.py +302 -0
- package/latticeai/core/embedding_providers/base.py +25 -0
- package/latticeai/core/embedding_providers/profiles.py +44 -0
- package/latticeai/core/embedding_providers/text.py +74 -8
- package/latticeai/core/http_origin.py +3 -3
- package/latticeai/core/messages.py +0 -5
- package/latticeai/core/policy.py +1 -6
- package/latticeai/core/quiet.py +1 -20
- package/latticeai/core/security.py +29 -83
- package/latticeai/core/sessions.py +95 -4
- package/latticeai/core/users.py +0 -38
- package/latticeai/core/vector_index/__init__.py +61 -0
- package/latticeai/core/vector_index/hnsw.py +383 -0
- package/latticeai/core/vector_index/sidecar.py +329 -0
- package/latticeai/models/router/catalog.py +2 -2
- package/latticeai/models/router/generation.py +176 -30
- package/latticeai/models/router/loading.py +150 -9
- package/latticeai/runtime/access_runtime.py +7 -4
- package/latticeai/runtime/brain_runtime.py +43 -9
- package/latticeai/runtime/build_phases/features.py +8 -31
- package/latticeai/runtime/build_phases/foundation.py +7 -16
- package/latticeai/runtime/build_phases/web.py +3 -3
- package/latticeai/runtime/build_phases/worker_profile.py +29 -27
- package/latticeai/runtime/runtime_context.py +0 -2
- package/latticeai/services/architecture_readiness.py +18 -19
- package/latticeai/services/process_audit.py +1 -22
- package/latticeai/services/product_readiness.py +39 -12
- package/latticeai/services/search_service.py +7 -0
- package/latticeai/services/voice_capture.py +8 -28
- package/latticeai/tools/__init__.py +12 -47
- package/latticeai/tools/commands.py +9 -15
- package/latticeai/tools/documents.py +12 -0
- package/latticeai/tools/knowledge.py +0 -6
- package/latticeai/tools/markup.py +152 -0
- package/package.json +4 -5
- package/requirements.txt +0 -1
- package/scripts/check_current_release_docs.mjs +1 -1
- package/scripts/check_openapi_drift.mjs +3 -2
- package/scripts/check_server_i18n.mjs +5 -4
- package/scripts/compose_openapi.py +4 -1
- package/scripts/export_openapi.py +5 -4
- package/scripts/gen_worker_allowlist_fixture.py +2 -2
- package/scripts/openapi_route_families.json +19 -74
- package/scripts/publish_release.mjs +157 -0
- package/scripts/release_screen_claims.json +144 -28
- package/src-tauri/Cargo.lock +45 -10
- package/src-tauri/Cargo.toml +1 -1
- package/src-tauri/tauri.conf.json +1 -1
- package/static/app/asset-manifest.json +47 -41
- package/static/app/assets/Act-Cf1L2709.js +2 -0
- package/static/app/assets/AdminConsole-DPAbLTYV.js +1 -0
- package/static/app/assets/Brain-DqamGrj-.js +2 -0
- package/static/app/assets/BrainHome-MHe2_RYs.js +2 -0
- package/static/app/assets/BrainSignals-CQPPfyyH.js +1 -0
- package/static/app/assets/Capture-DGdIH_Zc.js +1 -0
- package/static/app/assets/Chronicle-C-UlCJoJ.js +1 -0
- package/static/app/assets/CommandPalette-WNT4EqUX.js +1 -0
- package/static/app/assets/DigitalBrainExplorer-CEBH5Cwc.js +321 -0
- package/static/app/assets/Library-C6xd1dlf.js +1 -0
- package/static/app/assets/LivingBrain-BEk-0ohw.js +1 -0
- package/static/app/assets/ProductFlow-CZLm5iXh.js +1 -0
- package/static/app/assets/QueryClientProvider-B3OjqSyJ.js +1 -0
- package/static/app/assets/{ReviewCard-HXRle3qq.js → ReviewCard-CEHG6evf.js} +2 -2
- package/static/app/assets/RunsListPanel-CLtEJSRW.js +1 -0
- package/static/app/assets/System-CAxwBUXw.js +1 -0
- package/static/app/assets/WorkflowGraph-Dj10RuGE.js +1 -0
- package/static/app/assets/WorkflowsPanel-Kyeh_LIT.js +2 -0
- package/static/app/assets/actHelpers-CtSmK9Dw.js +1 -0
- package/static/app/assets/arrow-left-CRl5EO4D.js +1 -0
- package/static/app/assets/{bot-Cn8bWRuq.js → bot-DhUGRel2.js} +1 -1
- package/static/app/assets/brain-CLkhHsHF.js +1 -0
- package/static/app/assets/button-CmaEqG1T.js +1 -0
- package/static/app/assets/circle-check-CFgejkOS.js +1 -0
- package/static/app/assets/{circle-pause-CmzC_apg.js → circle-pause-l96izbxj.js} +1 -1
- package/static/app/assets/{circle-play-D8mW2aQ7.js → circle-play-CrZa25_q.js} +1 -1
- package/static/app/assets/{cpu-DZcdd0PZ.js → cpu-BaXudqwl.js} +1 -1
- package/static/app/assets/{download-bv1KEPGQ.js → download-hCVFPiyc.js} +1 -1
- package/static/app/assets/{folder-open-d-Pip5gr.js → folder-open-CHL82Yp7.js} +1 -1
- package/static/app/assets/{hard-drive-D20iavUb.js → hard-drive-DDzET7lk.js} +1 -1
- package/static/app/assets/index-CB93CZWW.css +2 -0
- package/static/app/assets/index-D2H-wSl6.js +13 -0
- package/static/app/assets/input-Df1CAY_I.js +1 -0
- package/static/app/assets/jsx-runtime-bzQ4Vb5N.js +1 -0
- package/static/app/assets/{link-2-BPJOFlAy.js → link-2-xNnTIX1_.js} +1 -1
- package/static/app/assets/{permissionCopy-ChdJd493.js → permissionCopy-D3aWHco-.js} +1 -1
- package/static/app/assets/primitives-BioD2slS.js +1 -0
- package/static/app/assets/search-BzBw8YcW.js +1 -0
- package/static/app/assets/{share-2-YNX_NtMU.js → share-2-FkzGf8Df.js} +1 -1
- package/static/app/assets/{shield-alert-DuQ3zrVL.js → shield-alert-B3dwzik4.js} +1 -1
- package/static/app/assets/sourceMeta-DQSY_tah.js +1 -0
- package/static/app/assets/textarea-P8o6pvOP.js +1 -0
- package/static/app/assets/useFocusTrap-hswOIkXE.js +1 -0
- package/static/app/assets/useMutation-OJLrYSRA.js +1 -0
- package/static/app/assets/workspace-BCuk3Ku9.js +1 -0
- package/static/app/index.html +4 -4
- package/static/sw.js +1 -1
- package/lattice_brain/ingestion/pipeline.py +0 -108
- package/latticeai/api/local_files.py +0 -44
- package/latticeai/api/tools.py +0 -126
- package/latticeai/api/voice_capture.py +0 -32
- package/latticeai/core/agent_permission.py +0 -85
- package/scripts/agent_eval.py +0 -34
- package/scripts/brain_quality_eval.py +0 -37
- package/scripts/check_legacy_debt.mjs +0 -91
- package/scripts/check_python.py +0 -100
- package/scripts/chunking_parity_corpus.py +0 -449
- package/scripts/generate_agent_parity_fixtures.py +0 -771
- package/scripts/generate_chunking_parity_fixtures.py +0 -259
- package/static/app/assets/Act-BPcVAbOL.js +0 -1
- package/static/app/assets/AdminConsole-Bw1ATQL0.js +0 -1
- package/static/app/assets/Brain-CT92Kos0.js +0 -321
- package/static/app/assets/BrainHome-CFBkt1K_.js +0 -2
- package/static/app/assets/BrainSignals-ReLWF2H8.js +0 -1
- package/static/app/assets/Capture-BsTokYkk.js +0 -1
- package/static/app/assets/Chronicle-B6f0T9id.js +0 -1
- package/static/app/assets/CommandPalette-CuvjTv1u.js +0 -1
- package/static/app/assets/Library-BGJbG9Hd.js +0 -1
- package/static/app/assets/LivingBrain-DGYK_Jsa.js +0 -1
- package/static/app/assets/ProductFlow-DXBC6brE.js +0 -1
- package/static/app/assets/System-CMHSO9qM.js +0 -1
- package/static/app/assets/arrow-left-BfmkskWx.js +0 -1
- package/static/app/assets/brain-CQJberbE.js +0 -1
- package/static/app/assets/button-Ct9f2_oT.js +0 -1
- package/static/app/assets/circle-check-DruOxB-4.js +0 -1
- package/static/app/assets/index-D9x-kSNy.css +0 -2
- package/static/app/assets/index-Do83hDzJ.js +0 -10
- package/static/app/assets/input-BLXVNmj1.js +0 -1
- package/static/app/assets/primitives-Cv5tbZBY.js +0 -1
- package/static/app/assets/search-CT9aho2j.js +0 -1
- package/static/app/assets/textarea-DqwLnli4.js +0 -1
- package/static/app/assets/useFocusTrap-ZVI98jaW.js +0 -1
- package/static/app/assets/useMutation-CVC4qv_D.js +0 -1
- package/static/app/assets/useQuery-C7BeG4HU.js +0 -1
- package/static/app/assets/utils-CiFtIdZq.js +0 -4
- package/static/app/assets/workspace-DQz9vIId.js +0 -1
package/docs/ROADMAP.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Lattice AI gap roadmap
|
|
2
|
+
|
|
3
|
+
> **Status: reference** — point-in-time inventory, redated at v12.0.0. Not a
|
|
4
|
+
> canonical current-release document; version gates do not bind it.
|
|
5
|
+
|
|
6
|
+
As of **2026-08-18**, against the 12.0.0 — Open House tree. The rows below
|
|
7
|
+
were gathered against 11.9.0 and re-checked when 12.0.0 shipped; what that
|
|
8
|
+
release closed is marked closed rather than deleted, so the ledger still
|
|
9
|
+
shows what was owed.
|
|
10
|
+
|
|
11
|
+
The owner's v12.0.0 priority was complexity management. The crate maps that
|
|
12
|
+
landed with that work are
|
|
13
|
+
[`rust/lattice-agent/ARCHITECTURE.md`](../rust/lattice-agent/ARCHITECTURE.md)
|
|
14
|
+
and
|
|
15
|
+
[`rust/lattice-platform/ARCHITECTURE.md`](../rust/lattice-platform/ARCHITECTURE.md);
|
|
16
|
+
the contributor path is [DEVELOPMENT.md](DEVELOPMENT.md). This page is the
|
|
17
|
+
honest leftover list, gathered from
|
|
18
|
+
[FEATURE_STATUS.md](../FEATURE_STATUS.md) Known Limitations and the §정직한
|
|
19
|
+
고지 sections of
|
|
20
|
+
[RELEASE_NOTES_v11.9.0.md](../RELEASE_NOTES_v11.9.0.md) and
|
|
21
|
+
[RELEASE_NOTES_v12.0.0.md](../RELEASE_NOTES_v12.0.0.md).
|
|
22
|
+
|
|
23
|
+
Four items those ledgers named **closed in 12.0.0**. They are kept below so
|
|
24
|
+
they are not re-opened as work. Everything else is still open.
|
|
25
|
+
|
|
26
|
+
Difficulty: **S** one focused change · **M** a vertical slice · **L** a
|
|
27
|
+
program (credentials, a model harness, or an index format).
|
|
28
|
+
|
|
29
|
+
## Closed in 12.0.0 — do not treat as open
|
|
30
|
+
|
|
31
|
+
| 무엇 | 어떻게 닫혔나 | 11.9.0 장부에 적혀 있던 말 |
|
|
32
|
+
| --- | --- | --- |
|
|
33
|
+
| Restore-then-read in a long-lived process | **Closed.** The store carries a generation epoch: a restore bumps it, connections opened under the old generation are stale at their next checkout, and the next read sees restored bytes. No restart. | 복원 뒤 커넥션이 재활용되기 전까지 복원 전 바이트를 줄 수 있다. |
|
|
34
|
+
| brew / pip setup items | **Closed, without turning into automation.** `/setup/install` runs brew/pip/uv for an item the request names *and* the server-derived allowlist contains; anything else is refused by name, and the default path is still manual. | 설계상 수동. |
|
|
35
|
+
| `POST /mcp` outside the OpenAPI product contract | **Closed.** Declared in the mount table as one JSON-RPC envelope operation, so it generates into the spec; natively mounted, so it is never proxied to the worker. | 계약 밖은 설계. |
|
|
36
|
+
| Pointer tools undeclared | **Closed.** `pip install "ltcai[pointer]"` is a named extra. A stock install still answers `pointer_tools=false` — the gap was the undeclared capability, not the default. | 재고 설치에서는 unavailable. |
|
|
37
|
+
|
|
38
|
+
Two more moved a long way without closing, and their rows below say so
|
|
39
|
+
rather than being deleted: the small-model harness (P1) and the HNSW index
|
|
40
|
+
(P2).
|
|
41
|
+
|
|
42
|
+
## P1 — default path is wrong or the headline lies
|
|
43
|
+
|
|
44
|
+
| 무엇 | 왜 남았나 | 난이도 | 우선순위 | 제안 경로 |
|
|
45
|
+
| --- | --- | --- | --- | --- |
|
|
46
|
+
| **Small-model agent-run content quality** | **Half closed in 12.0.0.** The mechanical half is done: the `guided` profile stops asking for JSON, the dial is chosen by a measured probe, a run that produces nothing demotes itself downward mid-run, and a 0.5B model reached `DONE` in 3.9s with a real file. The half still open is the *writing* — a weak summary fails the critic and the run ends `FAILED` / `NEEDS_REVIEW`. The cross-model matrix is improving from 11 of 18. | L | **P1** — still the voice the product ships on 8GB, and still the reason a first run can end in a review state. | Keep measuring with the loop's own parser, not a second harness. New answers go under new fixture keys (`agent_loop` `*_extended`); do not rewrite frozen rows. The remaining lever is content, not format: better plan→content prompting and a critic that says *what* was thin, per-model hacks still forbidden. |
|
|
47
|
+
| **Real-embedding default rollout** | **Narrowed in 12.0.0, not closed.** Auto-detection now adopts a real downloaded embedding model when one is present, the hash model is labelled `fallback` rather than presented as semantic, and vector identity is filtered by `(model, dim)` so two spaces cannot mix. What is still true: on a machine that has downloaded nothing, the default remains `lattice-local-hash-v1` (blake2 bag-of-features), and "semantic" recall is then a hash of tokens. | M | **P1** — recall is the product. Hash as a labelled fallback is fine; hash as the silent default is not. | Make the first-run flow offer the embedding model the way it offers a chat model, and keep the switch honest: drain the backlog through `lattice-jobs` so a change of embedder is a reindex, and report `stale_embedder` until the queue is empty. |
|
|
48
|
+
| **Worker-side batch embed** | **Mostly closed in 12.0.0 on the drain path**: embedding moved ahead of the write transaction, so the writer no longer holds a lock while a model runs — ~66 → ~1,300 items/s, and a 991-item backlog drains in 15.3s instead of ~40 minutes. What remains is the ingest-time door: it batches only when `(model_id, dim)` already agrees, and the hash path still embeds inline, one node at a time. | M | **P1** — the backlog path is fast now; a real-embed default still needs the inline door not to serialise against the single MLX executor. | Make `GraphWriter::write_vectors_with` + one `/worker/embed` call the ingest-time path whenever a provider is bound. Keep the drain planner as the backlog path. Do not open a second embedder inside `lattice-core`. |
|
|
49
|
+
|
|
50
|
+
## P2 — real, but the product still works without them
|
|
51
|
+
|
|
52
|
+
| 무엇 | 왜 남았나 | 난이도 | 우선순위 | 제안 경로 |
|
|
53
|
+
| --- | --- | --- | --- | --- |
|
|
54
|
+
| **HNSW whole-rebuild** | **Closed in 12.0.0; the default is deliberately unchanged.** The sidecar appends incrementally instead of being invalidated by every write, and the index is now used in real search: `hnsw+rescore` fetches `k * 8` candidate ids (cap 200) from `POST /worker/vector/query` and rescores exactly those rows natively, so recall is approximate and ordering is exact. Failures fall back to the exact scan carrying their reason. | L | **P2 → resolved for scale; the default stays `brute`.** | Nothing to build. The remaining decision is when to flip the default, and that needs recall@10 re-measured against the exact scan on a Brain that has been ingesting continuously — not a synthetic corpus. |
|
|
55
|
+
| **Unsigned DMG** | `Lattice AI_12.0.0_aarch64.dmg` is ad-hoc signed (= unsigned). First launch needs the Gatekeeper bypass. `npm run release:validate` checks names and presence, not a Developer ID. | M | **P2** — first-run tax on desktop, not a Brain bug. Needs an Apple identity. | Developer ID Application + notarization in the release path. Exact artifact name stays `dist/…` / `src-tauri/target/release/bundle/dmg/Lattice AI_X.Y.Z_aarch64.dmg`. Credentials stay off the tree. |
|
|
56
|
+
| **`api_key` cloud path is mock-only** | Contract-tested against a mock server. Never live-called — no billing budget. Live E2E is `cli_oauth` (`agy` / `grok`) at zero API billing. | S | **P2** — the supported cloud path already works. This is the paid-key twin. | One live contract test against a real OpenAI-compatible endpoint once a budget exists. Do not call the mock path "verified" in FEATURE_STATUS. Keep `local_only` winning on the request. |
|
|
57
|
+
| **Vault-watch full-resync** | **Largely closed in 12.0.0**: the ingest fingerprint (size + mtime + content sha256) is on the watch path, so an unchanged note is not re-read, re-chunked or re-embedded. The pass itself still runs once through the bridge, because link edges need node ids only a completed ingest has. Cap is still 2,000 notes/run (`truncated: true`), still off by default. | M | **P2** — the wasteful part is gone; the shape of the pass is unchanged. | Attach links from the ids that already landed so the bridge does not need a whole pass at all. Keep the 2,000 cap and the `truncated` flag. Inline `#tags` stay out of scope. Watch still never deletes — cleanup is the confirmed prune door. |
|
|
58
|
+
| **Self-Model has no screen** | Writes were restored in 11.7.0. `GET/POST/DELETE /api/memory/self-model*` and Review Center proposals work. `/app` has no profile view — "Brain이 나에 대해 뭐라고 생각하나" is an API call. | M | **P2** — the data path is real; the reader cannot see it. | A panel under `frontend/src/features/brain/` + `frontend/src/i18n/brain/`, reading the existing API. No new writer. Vitest 100% `all: true`. |
|
|
59
|
+
|
|
60
|
+
## P3 — honesty leftovers that should not grow
|
|
61
|
+
|
|
62
|
+
| 무엇 | 왜 남았나 | 난이도 | 우선순위 | 제안 경로 |
|
|
63
|
+
| --- | --- | --- | --- | --- |
|
|
64
|
+
| **API 오류 영어 리터럴** | FEATURE_STATUS carried a 10.9.0 inventory (17 of 50 *Python* routers) until 12.0.0 corrected it. After 11.6.0 the product routers are Rust. The live ratchet (`scripts/check_server_i18n.mjs`) locks **4** worker routers and reports **2** unclaimed (`health`, `search`). The larger leftover is native Rust `detail` strings that never entered `latticeai/core/messages.py`. | M | **P3** — the everyday SPA path is Korean. This is the remaining API/error English. | Finish the two worker routers (add them to `LOCALIZED`). Then a Rust-side catalog + a ratchet over `lattice-platform` / `lattice-auth` refusals. The 10.9.0 sentence is gone from FEATURE_STATUS as of 12.0.0; do not reintroduce it. |
|
|
65
|
+
| **Image evidence does not keep the original** | An `Image` citation shows the 96px inline `data:` thumbnail stored at ingest, capped at 24 KB. Serving the real file would need a new static route over the user's disk or a reuse of `/local/serve` (every read passes an explicit approval). | M | **P3** — the thumbnail is an honest preview, not a fake original. Missing the file is a proof gap, not a crash. | Approval-gated `/local/serve` (or a content-addressed blob route that still requires consent). Keep the `data:` thumbnail as the no-approval preview. Do not add an ungated static mount. |
|
|
66
|
+
|
|
67
|
+
## Other leftovers — named, not dropped
|
|
68
|
+
|
|
69
|
+
These stay on the honesty ledger through 12.0.0. They are not P1. Do not
|
|
70
|
+
quietly delete the row.
|
|
71
|
+
|
|
72
|
+
| 무엇 | 왜 남았나 | 난이도 | 우선순위 | 제안 경로 |
|
|
73
|
+
| --- | --- | --- | --- | --- |
|
|
74
|
+
| Self-Model extraction is a phrase table; no `refiner` is wired | First-person ko/en patterns only. Survivable because every candidate is a proposal. | M | P3 | Optional model `refiner` behind a flag; keep proposal-first. |
|
|
75
|
+
| Self-Model `open_keys` accepts `pending` only | Python also accepted `snoozed`. Port narrowed on purpose. | S | P3 | Add `snoozed` only with a fixture row, not a silent widening. |
|
|
76
|
+
| `delete_node` leaves the `PART_OF` edge | Same as Python. 12.0.0's prune door sidesteps it by using `delete_document_tree` (both directions, zero dangling); the primitive itself is unchanged. | S | P3 | Decide whether to cascade; do not "fix" it in one crate only. |
|
|
77
|
+
| `POST /knowledge-graph/ingest` is text-only | Contract, not a missing parser. Binary ingest is `/upload/document` → `/worker/parse`. | — | — | Keep. Document, do not "open it up". |
|
|
78
|
+
| Review mutation is two store cycles | One writer, two transactions. | M | P3 | Collapse only if a single txn can carry both without a second `workspace_os.json` writer. |
|
|
79
|
+
| Review events silent without an installed owner | Standalone retrieval process has no owner to attribute. | S | P3 | Fail closed to "unsigned event", never invent an owner. |
|
|
80
|
+
| Long download is not cancellable | Closing the tab leaves the pull running on its worker thread. | M | P3 | Cooperative cancel on `POST /models/load` / `prepare-model`. |
|
|
81
|
+
| Quantized vector backend: no memory win, ~2.2× slower | int8 codes are 8× smaller; peak RSS barely moves because SQLite rows dominate. | L | P3 | Hold as the representation a disk-resident index would need. Do not recommend it. |
|
|
82
|
+
| No vision or speech model ships; video needs `ffmpeg` | Runtime refusals, honestly labelled. | — | — | Keep. Nothing is fabricated to fill those fields. |
|
|
83
|
+
| Image/video observation functions have no HTTP door | 11.8.0 deleted the only route; it wrapped a native ingest that was never built. | M | P3 | Do not restore a door nobody calls. Ingest-time observation stays in Brain Core under unit test. |
|
|
84
|
+
| Text→image fusion needs a shared-space vision model | Off by default; the response says so when the tower is missing. | M | P3 | Keep the honesty. Do not return text-only ranking as if fusion ran. |
|
|
85
|
+
| Interop bridges read exports, never a vendor API | Notion zip, local git, local `.eml`/`.ics`. No IMAP, no Notion API. | L | P3 | Stay "point me at what you exported". |
|
|
86
|
+
| Reorganization is one topic level and has no one-click undo | `topics/<주제>/`; no delete path; putting files back is a new proposal. | M | P3 | A reverse proposal at apply-time if undo is wanted. |
|
|
87
|
+
| Browser extension language follows the browser | Separate origin; cannot read `lattice.language`. | M | P3 | Server-side language preference, then both clients read it. |
|
|
88
|
+
| No real-model CI runner | `agent-smoke.yml` was deleted because hosted runners have no MLX and the job failed open. | L | P3 | Restore only on a runner that actually loads a model. A fail-open job is worse than none. |
|
|
89
|
+
| Conversation artifact ledger is process-local | Minutes, not days. After restart, retrieval covers it. | S | P3 | Persist only if a test shows a user-visible hole after reboot. |
|
|
90
|
+
|
|
91
|
+
## Design boundaries — not a close-me
|
|
92
|
+
|
|
93
|
+
These were removed or scoped on purpose. A roadmap item that "restores
|
|
94
|
+
Telegram" or "turns hash embeddings back into the only story" is a product
|
|
95
|
+
decision, not a bug.
|
|
96
|
+
|
|
97
|
+
- Telegram bridge and SSO/OIDC login/callback — removed in 11.6.0 with the
|
|
98
|
+
platform code that became the worker. Password login is native; the SSO
|
|
99
|
+
*configuration* surface remains.
|
|
100
|
+
- Python coverage gate is a **line floor of 90** (11.8.0). Measured coverage
|
|
101
|
+
is much higher; the enforced claim is the floor.
|
|
102
|
+
- Frozen HTTP / agent / retrieval goldens keep keys for surfaces that no
|
|
103
|
+
longer exist. That is the point of a frozen record. Do not rewrite them to
|
|
104
|
+
match today's tree.
|
|
105
|
+
|
|
106
|
+
## How to use this
|
|
107
|
+
|
|
108
|
+
Close a row by changing the code, then moving the row into a release note
|
|
109
|
+
— not by editing this file ahead of the work. 12.0.0 shipped, so the four
|
|
110
|
+
rows it closed are marked closed above and the rows it moved say how far;
|
|
111
|
+
FEATURE_STATUS and the release notes carry the same statements. This
|
|
112
|
+
reference page is redated at each release, not silently rewritten to look
|
|
113
|
+
current.
|
package/docs/TRUST_MODEL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Lattice AI Trust Model
|
|
2
2
|
|
|
3
|
-
Current release: **
|
|
3
|
+
Current release: **12.0.0 — Open House**.
|
|
4
4
|
|
|
5
5
|
Lattice AI is local-first, explicit about external communication, and honest
|
|
6
6
|
when a capability is unavailable.
|
|
@@ -24,10 +24,18 @@ Local data can include:
|
|
|
24
24
|
|
|
25
25
|
External communication requires configuration plus a user/admin action:
|
|
26
26
|
|
|
27
|
-
- cloud model calls after
|
|
27
|
+
- cloud model calls after credentials resolve (`cloud_provider.json` / env
|
|
28
|
+
key / locally OAuth-authenticated `agy` or `grok`) and the escalation
|
|
29
|
+
policy — or an explicit `/cloud` prefix — uses them. Every such turn
|
|
30
|
+
writes a shape-only egress audit (provider / model / reason, never
|
|
31
|
+
content) and stages extracted knowledge as a Review Center proposal;
|
|
28
32
|
- model downloads from registries after install consent;
|
|
29
|
-
-
|
|
30
|
-
|
|
33
|
+
- package installs from `/setup/install` (brew / pip / uv) — only for an item
|
|
34
|
+
the request names that the **server-derived** allowlist also contains, with
|
|
35
|
+
the command taken from the server's own plan rather than from the request;
|
|
36
|
+
the default path remains manual;
|
|
37
|
+
- Telegram bridge — removed in 11.6.0 with the platform code that became
|
|
38
|
+
the AI worker; nothing replaces it;
|
|
31
39
|
- Brain Network peer actions after pairing;
|
|
32
40
|
- Docker/Postgres setup after opt-in scale configuration;
|
|
33
41
|
- update checks only when enabled;
|
|
@@ -51,9 +59,19 @@ Lattice AI should fail closed or show an unavailable state for:
|
|
|
51
59
|
- no graph/context evidence available;
|
|
52
60
|
- unavailable external integration;
|
|
53
61
|
- unknown or unreadable Knowledge Graph workspace scope;
|
|
54
|
-
-
|
|
62
|
+
- Telegram inbound (the bridge was removed in 11.6.0; nothing replaces it);
|
|
55
63
|
- wrong archive passphrase;
|
|
56
|
-
- archive tampering, unsupported archive versions, or path traversal
|
|
64
|
+
- archive tampering, unsupported archive versions, or path traversal;
|
|
65
|
+
- a hash-fallback embedder standing in for a real one — it is labelled
|
|
66
|
+
`fallback`, never presented as semantic recall;
|
|
67
|
+
- an opted-in approximate vector index that cannot answer — the search falls
|
|
68
|
+
back to the exact scan and carries the reason rather than returning a
|
|
69
|
+
shorter list;
|
|
70
|
+
- a model that cannot produce a tool call — the run is guided through numbered
|
|
71
|
+
choices under the same gates, and an unverifiable result is still
|
|
72
|
+
`NEEDS_REVIEW`;
|
|
73
|
+
- deleting knowledge — a vanished file is reported and only a confirmed prune
|
|
74
|
+
removes its subtree.
|
|
57
75
|
|
|
58
76
|
## Product Boundary
|
|
59
77
|
|
|
@@ -67,7 +85,10 @@ does not mean secrets should appear in clear text.
|
|
|
67
85
|
- Local files are only as protected as the user's machine, OS account, backups,
|
|
68
86
|
and disk encryption.
|
|
69
87
|
- Cloud model prompts follow the selected provider's policy once the user
|
|
70
|
-
explicitly chooses that provider
|
|
88
|
+
explicitly chooses that provider (or the `auto`/`always` escalation
|
|
89
|
+
policy does, behind `cloud_allowed`). The `api_key` path is
|
|
90
|
+
mock-verified only in this release; live OAuth used `cli_oauth` at
|
|
91
|
+
zero billing. Extracted cloud knowledge is proposal-first.
|
|
71
92
|
- A local admin can inspect local files and process memory outside Lattice AI.
|
|
72
93
|
- Marketplace and model registries are third-party services when explicitly
|
|
73
94
|
contacted.
|
package/docs/USABILITY_AUDIT.md
CHANGED
|
@@ -86,6 +86,11 @@ Heuristics:
|
|
|
86
86
|
|
|
87
87
|
## Journey 4 — Brain hierarchy
|
|
88
88
|
|
|
89
|
+
> **Dated snapshot (2026-07-21).** `DepthEmergence.tsx` was deleted in v11.8.0
|
|
90
|
+
> when the Brain home was redesigned; the depth-tiered reveal it describes is no
|
|
91
|
+
> longer how the home discloses structure. The findings below are kept as the
|
|
92
|
+
> record of what was evaluated at the time, not as current-truth surface notes.
|
|
93
|
+
|
|
89
94
|
Surface: `frontend/src/features/brain/DepthEmergence.tsx`,
|
|
90
95
|
`.../BrainMemoryLayer.tsx`.
|
|
91
96
|
|
package/docs/WHY_LATTICE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Why Lattice AI Exists
|
|
2
2
|
|
|
3
|
-
Current release: **
|
|
3
|
+
Current release: **12.0.0 — Open House**.
|
|
4
4
|
|
|
5
5
|
**Lattice AI is a local-first Digital Brain that keeps your knowledge durable
|
|
6
6
|
across any AI model.**
|
|
@@ -25,8 +25,9 @@ material. That breaks down for real work:
|
|
|
25
25
|
## The Lattice Answer
|
|
26
26
|
|
|
27
27
|
Lattice AI keeps conversations, documents, memories, decisions, relationships,
|
|
28
|
-
and source provenance in a private local Brain. Models can be local,
|
|
29
|
-
|
|
28
|
+
and source provenance in a private local Brain. Models can be local, or an
|
|
29
|
+
optional cloud worker you hire (OAuth CLI or an API key). Default is local.
|
|
30
|
+
The Brain remains.
|
|
30
31
|
|
|
31
32
|
The graph matters as visible proof, but a graph editor is not the product
|
|
32
33
|
identity. The product identity is a local-first Digital Brain: the user talks or
|
|
@@ -48,10 +49,17 @@ secondary.
|
|
|
48
49
|
- Ask what the team decided and see the source.
|
|
49
50
|
- Add documents and build a searchable private memory.
|
|
50
51
|
- Prepare from old notes, project decisions, and files.
|
|
51
|
-
- Preserve context when moving between models.
|
|
52
|
+
- Preserve context when moving between models. Cloud is optional; default
|
|
53
|
+
is local.
|
|
52
54
|
- Export or restore the Brain as an encrypted `.latticebrain` archive.
|
|
53
|
-
- Use Korean or English without changing the underlying Brain.
|
|
55
|
+
- Use Korean or English without changing the underlying Brain. Korean queries
|
|
56
|
+
are read as Korean, particles and all, rather than as strings that happen to
|
|
57
|
+
share a prefix.
|
|
54
58
|
- Avoid fake answers when no model or evidence is available.
|
|
59
|
+
- Run on the model your machine can actually hold. The loop measures what a
|
|
60
|
+
model can produce and adapts to it — a model too small to emit a tool call is
|
|
61
|
+
walked through numbered choices instead of being told it failed — with the
|
|
62
|
+
same permission gates and safeguards on every path.
|
|
55
63
|
|
|
56
64
|
## What Lattice AI Is Not
|
|
57
65
|
|
|
@@ -8,9 +8,9 @@ node to an injected *runner* that calls the real tool registry, skill registry,
|
|
|
8
8
|
plugin registry, or multi-agent orchestrator.
|
|
9
9
|
|
|
10
10
|
The execution model lives in
|
|
11
|
-
[`rust/lattice-platform/src/workflow_designer/definition.rs`](../rust/lattice-platform/src/workflow_designer/definition.rs)
|
|
11
|
+
[`rust/lattice-platform/src/governance/workflow_designer/definition.rs`](../rust/lattice-platform/src/governance/workflow_designer/definition.rs)
|
|
12
12
|
(pure logic with injected runners) and the HTTP surface lives in
|
|
13
|
-
[`rust/lattice-platform/src/workflow_designer/handlers.rs`](../rust/lattice-platform/src/workflow_designer/handlers.rs).
|
|
13
|
+
[`rust/lattice-platform/src/governance/workflow_designer/handlers.rs`](../rust/lattice-platform/src/governance/workflow_designer/handlers.rs).
|
|
14
14
|
Both moved from Python in 11.6.0.
|
|
15
15
|
Persistence reuses the existing `WorkspaceOSStore`, so pre-2.0 workflow history
|
|
16
16
|
is preserved.
|
package/docs/kg-schema.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Knowledge Graph Schema
|
|
2
2
|
|
|
3
|
-
Current release: **
|
|
3
|
+
Current release: **12.0.0 — Open House**.
|
|
4
4
|
|
|
5
5
|
명세 출처: `lattice_ai_full_spec.pptx` 슬라이드 20·21·22
|
|
6
6
|
구현: `lattice_brain/graph/schema.py`
|
|
@@ -106,6 +106,7 @@ Edge {
|
|
|
106
106
|
| `ORGANIZATION` | 조직 / 회사 / 팀 | `domain`, `members[]` |
|
|
107
107
|
| `WORKFLOW` | 워크플로우 정의/실행 | `workflow_id`, `status` |
|
|
108
108
|
| `AGENT` | 에이전트(역할/실행 주체) | `role`, `model_id` |
|
|
109
|
+
| `SECTION` | 문서의 한 절 (제목 하나가 덮는 범위) | `heading_path`, `depth`, `document` — v12.0.0부터 실제로 쓰인다 |
|
|
109
110
|
|
|
110
111
|
### 추가 엣지 타입
|
|
111
112
|
|
|
@@ -115,11 +116,48 @@ Edge {
|
|
|
115
116
|
| `MODIFIED_BY` | ANY → `PERSON` | 마지막 수정자 |
|
|
116
117
|
| `BELONGS_TO_PROJECT` | ANY → `PROJECT` | 프로젝트 귀속 |
|
|
117
118
|
| `PART_OF` | ANY → ANY | 구성요소 관계 |
|
|
119
|
+
| `HAS_CHUNK` | `SECTION` → `CHUNK` | 이 절에 속한 텍스트 |
|
|
120
|
+
| `CONTRADICTS` | ANY ↔ ANY | 두 진술이 서로 상충함 |
|
|
118
121
|
| `DISCUSSED_IN` | `CONCEPT`·`DECISION` → `MEETING`·`CHAT` | 어디에서 논의됨 |
|
|
119
122
|
| `DECIDED_BY` | `DECISION` → `PERSON` | 결정 주체 |
|
|
120
123
|
| `GENERATED_BY` | ANY → `AGENT`·`MODEL`·`WORKFLOW` | 생성 주체 |
|
|
121
124
|
| `USED_BY_AGENT` | ANY → `AGENT` | 에이전트가 사용함 |
|
|
122
125
|
|
|
126
|
+
### 섹션 트리 (v12.0.0)
|
|
127
|
+
|
|
128
|
+
`Section` 노드 타입과 `PART_OF` / `HAS_CHUNK` 엣지는 이전부터 분류 체계에
|
|
129
|
+
있었지만 **쓰는 사람이 없었다**. v12.0.0부터 타입드 청커의 `heading_path`
|
|
130
|
+
(`" > "`로 이어 붙인 제목 자취, 예: `아키텍처 > 저장소`)가 청크 메타데이터
|
|
131
|
+
문자열에서 멈추지 않고 그래프의 나무가 된다:
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
Document ──◄PART_OF── Section(아키텍처) ──◄PART_OF── Section(아키텍처 > 저장소)
|
|
135
|
+
│
|
|
136
|
+
HAS_CHUNK
|
|
137
|
+
▼
|
|
138
|
+
Chunk
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
| 요소 | 규칙 |
|
|
142
|
+
|------|------|
|
|
143
|
+
| `Section` 노드 | `label`은 그 절의 제목(마지막 마디), 전체 자취는 `attrs`에. id는 (문서, 제목 자취)의 결정적 해시라 재수집이 멱등이다 |
|
|
144
|
+
| `Section —PART_OF→ Section`·`Document` | 목차의 등뼈. 부모가 없는 최상위 절은 문서에 직접 붙는다 |
|
|
145
|
+
| `Section —HAS_CHUNK→ Chunk` | 어느 텍스트가 이 제목 아래 있는가 |
|
|
146
|
+
| 제목이 없는 문서 | **섹션을 만들지 않는다.** 파일마다 "제목 없는 절"을 하나씩 지어내면, 저자가 쓴 적 없는 것의 이름을 그래프에 넣는 셈이다 |
|
|
147
|
+
| 쓰기 경로 | 문서가 먼저 착지한 뒤 공개 `GraphWriter::upsert_nodes` / `upsert_edges` 문으로만 — 스키마는 넓어지지 않는다 |
|
|
148
|
+
|
|
149
|
+
이로써 「이 사실은 어느 절에서 나왔나」와 「그 절에 또 뭐가 있나」가 둘 다
|
|
150
|
+
답 가능한 질문이 된다. 릴리스 코퍼스 실측: 트리플 **555개 중 549개**가
|
|
151
|
+
섹션 출처를 가진다.
|
|
152
|
+
|
|
153
|
+
### 상충 관계와 근거 분류 (v12.0.0)
|
|
154
|
+
|
|
155
|
+
`CONTRADICTS`도 어휘에만 있던 타입이었다. v12.0.0부터 추출이 `PART_OF`와
|
|
156
|
+
`CONTRADICTS`를 **실제로 생산**하고, 엣지는 방향과 타입을 갖고 쓰이며,
|
|
157
|
+
`evidence`는 그 관계가 동사에서 왔는지 공기(co-occurrence)에서 왔는지로
|
|
158
|
+
분류되어 저장된다. 상충 자체는 자동으로 해소되지 않는다 — Review Center
|
|
159
|
+
제안으로 올라가고, 사람이 승인해야 `valid_from`/`valid_to`가 찍힌다.
|
|
160
|
+
|
|
123
161
|
### 통합 수집 형태 (Unified Ingestion)
|
|
124
162
|
|
|
125
163
|
모든 출처는 동일한 형태로 그래프에 들어온다:
|
|
@@ -142,8 +180,12 @@ provenance(source_type, source_uri, content_hash, captured_at, modified_at,
|
|
|
142
180
|
범위 없는 로컬 폴더는 개인 Brain으로 재투영하되 기존 노드 ID는 보존하며,
|
|
143
181
|
같은 폴더를 다른 워크스페이스로 조용히 재할당하지 않는다.
|
|
144
182
|
|
|
145
|
-
구현:
|
|
146
|
-
|
|
183
|
+
구현: 단일 진입점은 v11.6.0부터 Rust의 네이티브 ingest 문
|
|
184
|
+
(`lattice-ingest` → `lattice_core::graph_write`)이며, 파일/로컬폴더/URL/
|
|
185
|
+
브라우저 탭/텍스트를 모두 이 형태로 정규화한다. `lattice_brain/ingestion/`은
|
|
186
|
+
양쪽이 공유하는 어휘 — 라우팅 상수, DTO, 콘텐츠 해시, 추출 품질 점수 — 만
|
|
187
|
+
남았고, v11.8.0이 마지막 잔재였던 `IngestionPipeline` 능력 프로브 클래스를
|
|
188
|
+
그 유일한 호출 라우트와 함께 삭제했다.
|
|
147
189
|
|
|
148
190
|
---
|
|
149
191
|
|
|
@@ -224,10 +266,18 @@ v2 로 백필한다. 기존 `nodes` / `edges` 테이블은 삭제하지 않는
|
|
|
224
266
|
|
|
225
267
|
- 차원: 환경 변수 `LATTICEAI_EMBED_DIM` (기본 `1024`)
|
|
226
268
|
- 저장: SQLite `BLOB` 컬럼, `struct.pack('<{n}f', …)` 직렬화
|
|
227
|
-
- 검색: `
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
269
|
+
- 검색: 기본은 **정확 스캔(`brute`)** 코사인이다. v12.0.0부터
|
|
270
|
+
`LATTICEAI_VECTOR_INDEX=hnsw`를 켜면 워커 사이드카
|
|
271
|
+
(`POST /worker/vector/query`)가 `k * 8`개(최대 200) 후보 id를 주고,
|
|
272
|
+
네이티브 쪽이 **브루트와 같은 코사인으로 그 행들을 다시 채점**한다 —
|
|
273
|
+
근사 리콜, 정확 순서, 이름은 `hnsw+rescore`. 사이드카가 답하지 못하면
|
|
274
|
+
사유를 실은 채 정확 스캔으로 떨어진다. `.hnsw` 사이드카는 증분
|
|
275
|
+
append이므로 쓰기 한 번이 인덱스 전체를 무효화하지 않는다.
|
|
276
|
+
- 임베더: v12.0.0부터 **자동 감지**한다 — 다운로드된 실제 임베딩 모델이
|
|
277
|
+
있으면 채택하고, 없으면 해시 기반 폴백(`grade='fallback'`)을 **폴백이라고
|
|
278
|
+
표기한 채** 쓴다. 해시를 의미 벡터로 부르지 않는다. 벡터 정체성은
|
|
279
|
+
`(model, dim)`으로 필터되므로 서로 다른 임베딩 공간이 조용히 섞이지
|
|
280
|
+
않는다.
|
|
231
281
|
- 키워드 검색: v4 부터 FTS5 trigram 인덱스(`node_fts`) 가 LIKE 스캔을
|
|
232
282
|
대체한다 (한국어 부분 문자열 리콜 유지). FTS5/trigram 이 없는 SQLite
|
|
233
283
|
빌드에서는 LIKE 경로가 그대로 동작하며 `index_status().storage.fts_enabled`
|
package/docs/mcp-tools.md
CHANGED
|
@@ -4,7 +4,11 @@ Lattice AI는 MCP(Model Context Protocol) 서버로 동작하여 Claude Desktop,
|
|
|
4
4
|
|
|
5
5
|
## 연결 설정
|
|
6
6
|
|
|
7
|
-
`
|
|
7
|
+
The MCP surface is **streamable HTTP JSON-RPC** at `POST /mcp` on the
|
|
8
|
+
loopback gateway (default `http://localhost:4825`). There is no separate
|
|
9
|
+
stdio or SSE transport.
|
|
10
|
+
|
|
11
|
+
`claude_desktop_config.json` or Cursor MCP settings:
|
|
8
12
|
|
|
9
13
|
```json
|
|
10
14
|
{
|
|
@@ -16,112 +20,119 @@ Lattice AI는 MCP(Model Context Protocol) 서버로 동작하여 Claude Desktop,
|
|
|
16
20
|
}
|
|
17
21
|
```
|
|
18
22
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
Auth is the same session gate as every other product route:
|
|
24
|
+
|
|
25
|
+
- Loopback install with authentication off → the anonymous local owner (this
|
|
26
|
+
is what a localhost client such as Claude Desktop uses).
|
|
27
|
+
- Authentication on → send the `session_token` cookie or
|
|
28
|
+
`Authorization: Bearer <token>`.
|
|
29
|
+
|
|
30
|
+
Supported JSON-RPC methods: `initialize`, `notifications/initialized`,
|
|
31
|
+
`tools/list`, `tools/call`. Unknown methods return `-32601`. Notifications
|
|
32
|
+
have no result body (`202`).
|
|
33
|
+
|
|
34
|
+
Every native tool call goes through the existing tool governor. A governance
|
|
35
|
+
refusal is a JSON-RPC error (`-32001`), not a successful tool result.
|
|
36
|
+
|
|
37
|
+
**Since v12.0.0 `POST /mcp` is inside the OpenAPI product contract.** It is
|
|
38
|
+
declared in the gateway's mount table as a **single JSON-RPC envelope
|
|
39
|
+
operation** — one path, one method, one request/response shape, with the
|
|
40
|
+
method vocabulary above carried in the body rather than in the URL. Through
|
|
41
|
+
v11.9.0 it sat outside the contract by design; being outside a contract is not
|
|
42
|
+
the same as being safe to leave undescribed, so it is now generated into the
|
|
43
|
+
spec like every other product route. Two consequences worth knowing:
|
|
44
|
+
|
|
45
|
+
- The route is **natively mounted**, so it is answered in-process and never
|
|
46
|
+
proxied to the Python worker — the worker's committed allowlist does not
|
|
47
|
+
carry it, and the gateway forwards nothing that is not on that list.
|
|
48
|
+
- The agent loop reaches the same governance. A run's unified tool catalog
|
|
49
|
+
exposes `mcp.<tool>` beside native tools and skills, and dispatching one
|
|
50
|
+
runs the very governance check this endpoint runs. A name the run already
|
|
51
|
+
governs takes the stricter native path instead, so the MCP prefix can never
|
|
52
|
+
be the quieter way to call the same tool.
|
|
31
53
|
|
|
32
|
-
|
|
33
|
-
|------|------|--------|
|
|
34
|
-
| `run_command` | shell 없이 고정 read-only 명령 allowlist 실행 | 높음 |
|
|
35
|
-
| `run_terminal_command` | 터미널 명령 (별칭) | 높음 |
|
|
36
|
-
|
|
37
|
-
### 작업 관리
|
|
54
|
+
## 도구 목록
|
|
38
55
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
56
|
+
MCP exposes a **curated, read-oriented** subset of Lattice native tools,
|
|
57
|
+
plus each installed skill as a prompt asset. Writes, shell, desktop control,
|
|
58
|
+
and remote-install tools are **not** on this surface — use the REST `/tools/*`
|
|
59
|
+
routes (with their own approval gates) for those.
|
|
43
60
|
|
|
44
|
-
###
|
|
61
|
+
### Native (governed)
|
|
45
62
|
|
|
46
63
|
| 도구 | 설명 | 위험도 |
|
|
47
64
|
|------|------|--------|
|
|
48
|
-
| `
|
|
49
|
-
| `
|
|
50
|
-
| `
|
|
51
|
-
| `
|
|
52
|
-
| `
|
|
65
|
+
| `list_dir` | 워크스페이스 디렉터리 목록 (sandbox) | 낮음 |
|
|
66
|
+
| `read_file` | 워크스페이스 UTF-8 파일 읽기 (offset/limit) | 낮음 |
|
|
67
|
+
| `workspace_tree` | 재귀 트리 (깊이 제한) | 낮음 |
|
|
68
|
+
| `grep` | 워크스페이스 정규식 검색 | 낮음 |
|
|
69
|
+
| `knowledge_search` | 지식 정원 검색 (workspace scope, 승인 정책 적용) | 낮음 |
|
|
70
|
+
| `knowledge_tree` | 지식 정원 파일 목록 (동일 정책) | 낮음 |
|
|
71
|
+
| `git_status` | 워크스페이스 안 read-only `git status` | 낮음 |
|
|
53
72
|
|
|
54
|
-
###
|
|
73
|
+
### Skills (prompt assets)
|
|
55
74
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
| `read_docx` | Word 문서 읽기 | 낮음 |
|
|
61
|
-
| `read_xlsx` | Excel 파일 읽기 | 낮음 |
|
|
62
|
-
| `read_pptx` | PowerPoint 읽기 | 낮음 |
|
|
75
|
+
Installed skills from the skills directory appear as `skill.<name>`
|
|
76
|
+
(for example `skill.code_review`). `tools/list` serves the parsed
|
|
77
|
+
`schema.json` input schema. `tools/call` returns the `SKILL.md` body plus
|
|
78
|
+
the input echo — skills are not executables.
|
|
63
79
|
|
|
64
|
-
|
|
80
|
+
Typical names when the repo `skills/` tree is installed:
|
|
65
81
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
82
|
+
- `skill.code_review`
|
|
83
|
+
- `skill.data_analysis`
|
|
84
|
+
- `skill.file_edit`
|
|
85
|
+
- `skill.meeting_notes`
|
|
86
|
+
- `skill.summarize_document`
|
|
87
|
+
- `skill.web_search`
|
|
88
|
+
- `skill.weekly_review`
|
|
71
89
|
|
|
72
|
-
## REST API
|
|
90
|
+
## REST API
|
|
73
91
|
|
|
74
|
-
|
|
92
|
+
The same governed subset is also reachable at `POST /mcp/call`
|
|
93
|
+
(`{"action": "...", "args": {}}`) and the existing `/tools/*` routes.
|
|
75
94
|
|
|
76
95
|
```bash
|
|
77
|
-
#
|
|
78
|
-
curl -
|
|
79
|
-
"
|
|
96
|
+
# MCP JSON-RPC initialize
|
|
97
|
+
curl -s -X POST http://localhost:4825/mcp \
|
|
98
|
+
-H "Content-Type: application/json" \
|
|
99
|
+
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"curl","version":"0"}}}'
|
|
80
100
|
|
|
81
|
-
#
|
|
82
|
-
curl -b "
|
|
83
|
-
http://localhost:4825/tools/edit_file \
|
|
101
|
+
# MCP tools/call
|
|
102
|
+
curl -s -b "session_token=<token>" -X POST http://localhost:4825/mcp \
|
|
84
103
|
-H "Content-Type: application/json" \
|
|
85
|
-
-d '{"
|
|
104
|
+
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"list_dir","arguments":{"path":"."}}}'
|
|
86
105
|
|
|
87
|
-
#
|
|
88
|
-
curl -b "
|
|
89
|
-
"
|
|
106
|
+
# REST sibling (same dispatch)
|
|
107
|
+
curl -s -b "session_token=<token>" -X POST http://localhost:4825/mcp/call \
|
|
108
|
+
-H "Content-Type: application/json" \
|
|
109
|
+
-d '{"action":"list_dir","args":{"path":"."}}'
|
|
90
110
|
|
|
91
|
-
#
|
|
92
|
-
curl -b "
|
|
93
|
-
http://localhost:4825/tools/run_command \
|
|
111
|
+
# Full write/exec surface (not on MCP)
|
|
112
|
+
curl -s -b "session_token=<token>" -X POST http://localhost:4825/tools/edit_file \
|
|
94
113
|
-H "Content-Type: application/json" \
|
|
95
|
-
-d '{"
|
|
114
|
+
-d '{"path": "server.py", "old_string": "old code", "new_string": "new code"}'
|
|
96
115
|
```
|
|
97
116
|
|
|
98
|
-
`run_command
|
|
99
|
-
Python/Node/npm/npx/sed, shell
|
|
100
|
-
|
|
101
|
-
|
|
117
|
+
`run_command` remains a REST-only admin tool. It allows `pwd`, `ls`, `find`,
|
|
118
|
+
`cat`, `head`, `tail`, `wc`, `rg` only. Python/Node/npm/npx/sed, shell
|
|
119
|
+
operators, executable paths, absolute paths, `..` traversal, workspace-outside
|
|
120
|
+
symlinks, `rg --pre`, and `find -exec/-delete` are refused.
|
|
102
121
|
|
|
103
122
|
## 도구 카탈로그 조회
|
|
104
123
|
|
|
105
124
|
```bash
|
|
106
|
-
curl -b "
|
|
125
|
+
curl -b "session_token=<token>" http://localhost:4825/mcp/tools
|
|
107
126
|
```
|
|
108
127
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
"risk": "medium",
|
|
117
|
-
"parameters": { ... }
|
|
118
|
-
},
|
|
119
|
-
...
|
|
120
|
-
]
|
|
121
|
-
}
|
|
122
|
-
```
|
|
128
|
+
`GET /mcp/tools` lists Lattice's native tool catalog (names, descriptions,
|
|
129
|
+
governance). `tools/list` on `POST /mcp` is the MCP-shaped list with JSON
|
|
130
|
+
Schemas for the curated subset plus skills.
|
|
131
|
+
|
|
132
|
+
`POST /mcp/install` enables a skill or plugin Lattice can actually flip in
|
|
133
|
+
the workspace registry. Remote npm/pip/connector entries return
|
|
134
|
+
`{"status":"manual_required", ...}` instead of a blank 404.
|
|
123
135
|
|
|
124
|
-
|
|
125
|
-
MCP/plugin dispatch
|
|
126
|
-
|
|
127
|
-
사용합니다.
|
|
136
|
+
The catalogs require authentication and do not return the absolute
|
|
137
|
+
`AGENT_ROOT`. MCP/plugin dispatch cannot bypass user, workspace, capability,
|
|
138
|
+
or approval policy. Knowledge-garden reads use explicit user/workspace scope.
|
package/docs/security-model.md
CHANGED
|
@@ -88,9 +88,12 @@ MAGIC_NUMBERS = {
|
|
|
88
88
|
|
|
89
89
|
## 수집 & 그래프 포터빌리티 보안 (v3.6.0)
|
|
90
90
|
|
|
91
|
-
- **수집 라이프사이클**: 모든 수집은 `
|
|
92
|
-
|
|
93
|
-
정직하게 `status="blocked"`로
|
|
91
|
+
- **수집 라이프사이클**: 모든 수집은 네이티브 ingest 문(`lattice-ingest` →
|
|
92
|
+
`lattice_core::graph_write`) → 도구 디스패치를 거쳐 `pre_tool`/`post_tool`
|
|
93
|
+
훅이 발화됩니다. `pre_tool`이 차단하면 수집은 정직하게 `status="blocked"`로
|
|
94
|
+
거부됩니다(권한 게이트·민감정보 가드 적용). v3.6.0에 이 계약을 세운 것은
|
|
95
|
+
Python `IngestionPipeline.ingest`였고, v11.6.0이 문을 Rust로 옮기면서 계약은
|
|
96
|
+
그대로 유지했습니다.
|
|
94
97
|
- **웹 URL 읽기**(`/api/browser/read-url`): `http(s)`만 허용하고 DNS의 모든 결과에서
|
|
95
98
|
loopback/private/link-local/multicast/reserved 주소를 거부합니다. 검증한 IP에 연결을
|
|
96
99
|
고정해 DNS rebinding을 막고, redirect마다 재검증하며 환경 proxy를 사용하지
|