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/DEVELOPMENT.md
CHANGED
|
@@ -3,13 +3,16 @@
|
|
|
3
3
|
> **Status: canonical** — current contributor guidance, kept in sync with the
|
|
4
4
|
> current release.
|
|
5
5
|
|
|
6
|
-
Current release: **
|
|
6
|
+
Current release: **12.0.0 — Open House**.
|
|
7
7
|
|
|
8
|
-
This document is
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
(
|
|
12
|
-
11.
|
|
8
|
+
This document is the contributor onboarding path: how to boot the tree, where
|
|
9
|
+
a change belongs, which gates will go red, and the house rules that keep the
|
|
10
|
+
product honest. Product positioning and the five-minute first-run stay in
|
|
11
|
+
[README.md](../README.md) and [ONBOARDING.md](ONBOARDING.md). Supported
|
|
12
|
+
release history is 11.0.0 and later in [CHANGELOG.md](CHANGELOG.md) and
|
|
13
|
+
[RELEASE.md](../RELEASE.md) (11.6.0 rebuilt the product server in Rust, so
|
|
14
|
+
[SECURITY.md](../SECURITY.md) supports only 11.x). Open gaps toward v12.0.0
|
|
15
|
+
live in [ROADMAP.md](ROADMAP.md) (reference, not canonical).
|
|
13
16
|
|
|
14
17
|
## Product Contract
|
|
15
18
|
|
|
@@ -18,8 +21,7 @@ across any AI model.
|
|
|
18
21
|
|
|
19
22
|
Engineering work should preserve these boundaries:
|
|
20
23
|
|
|
21
|
-
- the Brain is the durable asset;
|
|
22
|
-
- models are replaceable voices;
|
|
24
|
+
- the Brain is the durable asset; models are replaceable voices;
|
|
23
25
|
- SQLite is the live local Brain store;
|
|
24
26
|
- Docker, cloud models, downloads, update checks and Brain Network are opt-in
|
|
25
27
|
(the PostgreSQL scale/migration tooling and the Telegram bridge left the tree
|
|
@@ -28,140 +30,306 @@ Engineering work should preserve these boundaries:
|
|
|
28
30
|
calls;
|
|
29
31
|
- normal Brain use must stay separate from Admin/operator controls.
|
|
30
32
|
|
|
31
|
-
##
|
|
33
|
+
## 10-minute quickstart
|
|
34
|
+
|
|
35
|
+
Need Python 3.11+, Node, and a Rust toolchain (`cargo`). The product is
|
|
36
|
+
`lattice-host`; Python is the 20-route compute worker it supervises.
|
|
32
37
|
|
|
33
38
|
```bash
|
|
34
|
-
|
|
35
|
-
|
|
39
|
+
git clone <this-repo>
|
|
40
|
+
cd "Lattice AI" # or whatever the directory is named
|
|
41
|
+
|
|
42
|
+
python3 -m venv .venv
|
|
43
|
+
.venv/bin/pip install -U pip
|
|
44
|
+
.venv/bin/pip install -e ".[dev]"
|
|
45
|
+
|
|
46
|
+
npm ci
|
|
47
|
+
npm start # product. If PATH has a stale global LTCAI: node bin/ltcai.js
|
|
36
48
|
```
|
|
37
49
|
|
|
38
|
-
|
|
50
|
+
Then open:
|
|
39
51
|
|
|
40
52
|
```text
|
|
41
53
|
http://127.0.0.1:4825/app
|
|
42
54
|
```
|
|
43
55
|
|
|
44
|
-
|
|
56
|
+
The first screen is the wake step: language switcher (한국어 / English), the
|
|
57
|
+
Living Brain, and the Korean headline **「내 지식이 살아나는 Brain을 시작하세요.」**
|
|
58
|
+
with the primary **「Brain 지금 깨우기」**. An existing local Brain can skip
|
|
59
|
+
into the home canvas.
|
|
60
|
+
|
|
61
|
+
Apple Silicon local-model extras (MLX), only if you will load a model:
|
|
45
62
|
|
|
46
63
|
```bash
|
|
47
|
-
pip install "
|
|
64
|
+
.venv/bin/pip install -e ".[local]"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### `npm start` vs `npm run dev`
|
|
68
|
+
|
|
69
|
+
| command | what it actually is | what you get |
|
|
70
|
+
| --- | --- | --- |
|
|
71
|
+
| `npm start` | the `LTCAI` bin → [`bin/ltcai.js`](../bin/ltcai.js) | **the product**: `lattice-host` on `127.0.0.1:4825`, supervising the worker, serving the SPA at `/app` |
|
|
72
|
+
| `node bin/ltcai.js` | the same bin, called directly | same product; use this if a stale global `LTCAI` is on `PATH` |
|
|
73
|
+
| `npm run dev` | `node scripts/run_python.mjs -m latticeai.cli.entrypoint --reload` | **not the product**. The 20-route worker with uvicorn `--reload`. Prints `Lattice AI worker on http://127.0.0.1:4825`. There is no SPA. |
|
|
74
|
+
|
|
75
|
+
`scripts/run_python.mjs` prefers `.venv/bin/python`. `bin/ltcai.js` prefers
|
|
76
|
+
`LTCAI_PYTHON`, then a managed `~/.ltcai/npm-python`, then `.venv`. Pin the
|
|
77
|
+
worker interpreter with `LTCAI_PYTHON` when both exist.
|
|
78
|
+
|
|
79
|
+
`bin/ltcai.js` looks for the host at `LATTICEAI_HOST_BIN` / `LTCAI_HOST`, then
|
|
80
|
+
`rust/target/release/lattice-host`, then `rust/target/debug/lattice-host`. If
|
|
81
|
+
none exist it runs `cargo build -p lattice-host` (debug). A stale
|
|
82
|
+
`rust/target/release/lattice-host` wins over a current debug binary — pin or
|
|
83
|
+
rebuild (`cargo build -p lattice-host --release`) if `-V` is not 12.0.0.
|
|
84
|
+
|
|
85
|
+
Do not run `npm start` and `npm run dev` on the same port. The worker
|
|
86
|
+
entrypoint defaults to `LATTICEAI_PORT` or **4825**, the same port as the
|
|
87
|
+
product. Iterate on worker compute with
|
|
88
|
+
`LATTICEAI_PORT=4835 npm run dev` (and `--no-spawn` / a pinned worker port on
|
|
89
|
+
the host if you are pairing them).
|
|
90
|
+
|
|
91
|
+
## The map — 어디에 무엇을
|
|
92
|
+
|
|
93
|
+
Two crate-local maps are the contract. This table is the index; they are the
|
|
94
|
+
detail. Read the matching `mod.rs` before adding a file.
|
|
95
|
+
|
|
96
|
+
- [`rust/lattice-agent/ARCHITECTURE.md`](../rust/lattice-agent/ARCHITECTURE.md)
|
|
97
|
+
— `kernel/` decides; `parse/` `content/` `tools/` never import the kernel;
|
|
98
|
+
`surface/` carries HTTP; `prompts/` fills a blank. Arrows point down only.
|
|
99
|
+
- [`rust/lattice-platform/ARCHITECTURE.md`](../rust/lattice-platform/ARCHITECTURE.md)
|
|
100
|
+
— this crate **offers**. It does not decide whether a run is allowed
|
|
101
|
+
(`lattice-agent` kernel) and it does not own what is true (`lattice-core`).
|
|
102
|
+
|
|
103
|
+
```text
|
|
104
|
+
lattice-host one door — mounts every family
|
|
105
|
+
lattice-platform what the product offers
|
|
106
|
+
workspaceos/ place, people, dials, workspace_os.json
|
|
107
|
+
toolsurface/ MCP, tools, plugins, agents, computer-use
|
|
108
|
+
governance/ review, proposals, automation, workflows, hooks
|
|
109
|
+
knowledge/ export/import/backup, network, boundary, voice
|
|
110
|
+
modelops/ catalog, recommendations, setup
|
|
111
|
+
adminops/ audit, security dashboard, funnel
|
|
112
|
+
shell/ SPA + 308 redirects
|
|
113
|
+
lattice-agent may it run, and what does it do
|
|
114
|
+
lattice-core what is true — GraphWriter is the only graph writer
|
|
115
|
+
lattice-retrieval search, memory, chronicle, command, evidence
|
|
116
|
+
lattice-ingest files, folders, browser capture
|
|
117
|
+
lattice-jobs embed drain + index API
|
|
118
|
+
lattice-chat POST /chat
|
|
119
|
+
lattice-auth who is this
|
|
120
|
+
Python worker compute only — 19 allowlisted routes
|
|
121
|
+
frontend/src SPA
|
|
48
122
|
```
|
|
49
123
|
|
|
50
|
-
|
|
124
|
+
Compatibility re-exports at each crate's `src/lib.rs` keep the pre-v12 paths
|
|
125
|
+
working for *consumers*. New code inside a crate uses the real path
|
|
126
|
+
(`crate::kernel::state`, `crate::adminops::admin`).
|
|
127
|
+
|
|
128
|
+
| 할 일 | 어디에 | 하지 말 것 |
|
|
129
|
+
| --- | --- | --- |
|
|
130
|
+
| **새 제품 API 라우트** | The `lattice-platform` domain that names the subject (`workspaceos/`, `toolsurface/`, `governance/`, `knowledge/`, `modelops/`, `adminops/`). One module owns one family: `MOUNTED: &[(&str, &str)]` + `router(state)`, then mount the factory in [`rust/lattice-host/src/gateway/product.rs`](../rust/lattice-host/src/gateway/product.rs). A **page shell** is a 308 in `shell/ui_redirects`, not a second handler — except `GET /plugins/sdk` (it carries `require_user`, so it is `toolsurface::plugins`). | Do not put retrieval/search/chronicle in platform — that is `lattice-retrieval`. Ingest doors are `lattice-ingest`. Chat is `lattice-chat`. Index drain is `lattice-jobs`. Identity is `lattice-auth`. Agent-loop HTTP is `lattice-agent` `surface/`. A handler here that re-derives "is this allowed" has forked `lattice_agent::kernel::permission`. A module that opens the graph has become a second writer. |
|
|
131
|
+
| **에이전트 툴 추가** | A tool that runs *inside an agent turn* goes in `lattice-agent` `tools/`, in the file named for what it *touches*: `files` (workspace), `vault` (Brain/Obsidian), `shell` (subprocesses), `desktop` (OS actuation), `render` (document creators), `scaffold` (templates), `local` (paths outside the workspace). Add the name to `tools::host::MUTATING_TOOLS` or `RENDER_TOOLS` and the arm to the dispatcher in [`tools/host.rs`](../rust/lattice-agent/src/tools/host.rs). `is_native` follows from those tables. Every path resolves through `tools::sandbox::Workspace::resolve`; every write passes `content::sanitize::sanitize_write_content`. HTTP exposure of an existing capability is `lattice-platform` `toolsurface/tools/` plus `tools::governance_for` — not a second implementation. | Do not add a permission check in the handler — the kernel already said yes. Do not `std::fs` a raw path. Do not put a read-only compute handler here; those stay on the worker (`POST /agent/tool`). Pointer tools (`computer_*` click/move/type/…) stay on the worker on purpose. |
|
|
132
|
+
| **파싱 러그 추가** | `lattice-agent` `parse/action.rs` (or `parse/channel.rs` for a new model-family frame). Append it to the ordered chain — cheapest and most literal first — and **name it in the returned `repairs` list**. CPython primitives (`pyjson`, `pyliteral`, `pyshlex`, `pystr`) are pinned by [`rust/fixtures/agent/`](../rust/fixtures/agent/FROZEN.md). New answers that Python never gave live under **new keys** (see [`agent_loop/FROZEN.md`](../rust/fixtures/agent_loop/FROZEN.md) `*_extended`). | A silent repair is a bug. Never supply a tool name, path, or argument the model did not write. Do not put a decision here (that is `kernel/`) or file-body salvage (that is `content/`). Do not rewrite a frozen row in place. |
|
|
133
|
+
| **새 워커 계산** | Compute only — embed, parse, extract, render, ASR, LLM. Add the handler next to its family (`latticeai/api/worker_compute.py` for the `/worker/*` seams, or `WORKER_ROUTES` / `WORKER_SEAM_ROUTES` in [`latticeai/runtime/build_phases/worker_profile.py`](../latticeai/runtime/build_phases/worker_profile.py) if it is a model/engine door). Append `(method, path)` to the matching tuple. Regenerate the committed projection: `.venv/bin/python scripts/gen_worker_allowlist_fixture.py`. `tests/unit/test_worker_allowlist.py` pins the file; `lattice-host` `include_str!`s [`rust/fixtures/worker_allowlist.json`](../rust/fixtures/worker_allowlist.json). There are **19** routes. Anything not native and not on that list is `404`. | Do not add a worker route for a product feature. The worker stores nothing — no graph, no sessions, no files. `latticeai.app_factory.build_context` is the **worker** composition root (`create_worker_app`); it is not the product. Import of `latticeai.app_factory` must stay free of MLX/GPU init, singleton construction, filesystem writes, and network calls. |
|
|
134
|
+
| **프론트 화면 / 패널** | Route screens in `frontend/src/pages/` (`Brain`, `Capture`, `Chronicle`, `Act`, `Library`, `System`). Feature panels in `frontend/src/features/<area>/`. Shared chrome in `frontend/src/components/`. Hash routes and aliases in `frontend/src/routes.ts`. Copy in `frontend/src/i18n/`: one namespace module calls `registerCopy` (`shell` is eager; `brain`, `workspace`, `onboarding`, `chronicle` register from the lazy route). Author Korean first; ship the English pair in the same module. `t()` falls back to `COPY.ko`. Colors from [`frontend/src/styles/tokens.css`](../frontend/src/styles/tokens.css) as `hsl(var(--token))`; surface rules in the narrowest file under `frontend/src/styles/experience/`. Brain behavior belongs in `useBrainChat` / `useBrainHistory` / `useBrainIngestion` / `useBrainProof`. Failed `ApiResult` stays an unavailable/error state. Colocate a Vitest file; the floor is 100% `all: true`. | No user-facing English/Korean literals in TSX (`scripts/check_i18n_literals.mjs`). Do not import a namespace you do not register (`check:i18n-namespaces`). Do not add a competing shell rule to `styles.css`. Do not put runtime metrics or admin tools on the default first screen. Regenerate `frontend/src/api/openapi.ts` with `npm run frontend:openapi` when a contract changes — do not edit it by hand. |
|
|
135
|
+
| **지식 그래프 쓰기** | [`lattice_core::graph_write::GraphWriter`](../rust/lattice-core/src/graph_write/mod.rs) only. Public doors: `open` / `with_parts`; ingest `ingest_file` / `ingest_content` / `ingest_message` / `ingest_event`; vectors `write_vectors` / `write_vectors_with` / `rebuild_vector_index`; curation `curate` / `curate_scan` / `curate_noise` / promotions / `mark_superseded`; documents `delete_document_tree` / `delete_node` / `set_node_sensitivity` / `stamp_node_validity` / `set_local_source_watch` / `remove_local_source` / `upsert_nodes` / `upsert_edges`; provenance `record_ingestion` / `import_graph_data`. Production `open()` stamps `"personal"` when a write omits a workspace. Chunks, concepts, triples and embeddings arrive as *data* on the request types — the writer never calls a model. | Do not open `knowledge_graph.sqlite` for writing from another crate. Do not go through the retired `/worker/graph/mutate`. `with_parts` leaves `default_workspace` unset so frozen goldens keep their legacy-null rows — that constructor is for parity, not the product. |
|
|
136
|
+
| **검증 / 골든** | Each family has a `FROZEN.md` stating what wrote it and that it must not be regenerated. **Agent kernel** — [`rust/fixtures/agent/`](../rust/fixtures/agent/FROZEN.md), `lattice-agent` `tests/parity.rs`. **Agent loop** — [`rust/fixtures/agent_loop/`](../rust/fixtures/agent_loop/FROZEN.md), `tests/agent_loop.rs`. **Retrieval / embeddings** — [`rust/fixtures/golden/`](../rust/fixtures/golden/FROZEN.md), `lattice-retrieval` + `lattice-core` `tests/golden_embeddings.rs`. **Graph writes** — [`rust/fixtures/graph_write/`](../rust/fixtures/graph_write/FROZEN.md). **Chunking** — [`rust/fixtures/chunking/`](../rust/fixtures/chunking/FROZEN.md), `lattice-ingest`. **HTTP replay** — [`rust/fixtures/http/`](../rust/fixtures/http/FROZEN.md). Python worker: `npm run test:unit`. SPA: `npm run test:frontend`. Visual: `npm run test:visual`. Integration starts its own loopback host with disposable HOME/data and refuses non-loopback URLs (`npm run test:integration`). | Frozen expected values are inviolable. If the port disagrees, **the port changed** — fix the port. A deliberate new answer goes under a **new key** (or a new file) and is named as not-parity; do not edit a row in place. Do not resurrect a deleted generator to "refresh" a golden. |
|
|
137
|
+
|
|
138
|
+
A new gate or verdict goes in `lattice-agent` `kernel/` and fails **closed**:
|
|
139
|
+
unknown is a refusal, an unreachable verifier is `NEEDS_REVIEW`, a policy-less
|
|
140
|
+
tool is its most dangerous plausible class. Gate order is pinned by the agent
|
|
141
|
+
goldens; reordering is a behaviour change.
|
|
142
|
+
|
|
143
|
+
A new built-in prompt goes in `prompts/mod.rs` as a constant plus the test that
|
|
144
|
+
feeds it through the real parser. A caller-supplied prompt always wins.
|
|
145
|
+
|
|
146
|
+
`workspace_os.json` has exactly one writer:
|
|
147
|
+
`workspaceos::workspace::store::WorkspaceOsStore`. Governance's
|
|
148
|
+
`GovernanceState` is a facade over the same `Arc`. Audit lines go through
|
|
149
|
+
`adminops::admin::append_audit_event` only.
|
|
150
|
+
|
|
151
|
+
## The gates
|
|
51
152
|
|
|
52
|
-
Run the smallest affected gate while iterating. Before committing broad
|
|
53
|
-
API, UI, or release work
|
|
153
|
+
Run the smallest affected gate while iterating. Before committing broad
|
|
154
|
+
runtime, API, UI, or release work:
|
|
54
155
|
|
|
55
156
|
```bash
|
|
56
|
-
npm run check:python
|
|
57
157
|
npm run lint
|
|
58
158
|
npm run typecheck
|
|
59
159
|
npm run test:frontend
|
|
60
160
|
npm run test:unit
|
|
61
161
|
npm run docs:check-links
|
|
162
|
+
npm run rust:lint # fmt --check + clippy -D warnings
|
|
163
|
+
npm run rust:test
|
|
62
164
|
```
|
|
63
165
|
|
|
64
|
-
`npm run lint` runs the Python Ruff baseline, frontend TypeScript lint gate,
|
|
65
|
-
visual smoke syntax checks, an exact generated-OpenAPI drift check, i18n literal
|
|
66
|
-
checks, and browser-extension syntax/behavior tests.
|
|
67
|
-
|
|
68
166
|
Use these when the change touches the relevant surface:
|
|
69
167
|
|
|
70
168
|
```bash
|
|
71
169
|
npm run test:integration
|
|
72
170
|
npm run test:visual
|
|
171
|
+
npm run test:coverage
|
|
172
|
+
npm run test:frontend:coverage
|
|
73
173
|
npm run desktop:tauri:check
|
|
74
174
|
npm run release:evidence
|
|
75
175
|
npm run release:artifacts
|
|
76
176
|
npm run release:validate
|
|
77
177
|
```
|
|
78
178
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
`
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
`
|
|
89
|
-
`
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
`
|
|
94
|
-
`
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
`
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
179
|
+
### `npm run lint` — ten members, in this order
|
|
180
|
+
|
|
181
|
+
1. `lint:python` — `ruff check .` then `mypy`. Fix ruff locally (`ruff check --fix`) before arguing with the rule; mypy errors name the module under `latticeai/` or `lattice_brain/`.
|
|
182
|
+
2. `lint:visual` — `node --check` on every `tests/visual/*.js`, `*.cjs`, and `tests/visual/mock_server/*.cjs`. A syntax error in a screenshot spec fails here, not in Playwright.
|
|
183
|
+
3. `lint:frontend` — `scripts/lint_frontend.mjs`: `tsc --noEmit` plus static checks over `frontend/` and `static/app`.
|
|
184
|
+
4. `frontend:openapi:check` — `frontend/openapi.json` and `frontend/src/api/openapi.ts` must match a fresh isolated export. Fix: `npm run frontend:openapi` and commit both artifacts.
|
|
185
|
+
5. `scripts/check_i18n_literals.mjs` — no user-facing string literals in `frontend/src` TS/TSX. Move the words into the matching `frontend/src/i18n/` namespace (both `ko` and `en`).
|
|
186
|
+
6. `check:i18n-namespaces` — a lazy chunk may only read keys whose namespace it imports. Import the namespace module from the route, do not reach into a sibling dictionary.
|
|
187
|
+
7. `check:bundle` — initial JS gzip closure stays under 150 KiB. Heavy UI belongs behind `React.lazy`. Do not raise the budget to hide a sync import.
|
|
188
|
+
8. `check:server-i18n` — routers listed in `scripts/check_server_i18n.mjs` must raise through `http_error` / `translate`, never a quoted `detail=`. Adding a name to `LOCALIZED` is how a migration is declared finished. Today it locks 4 worker routers and reports 2 unclaimed (`health`, `search`).
|
|
189
|
+
9. `scripts/check_release_evidence_bound.mjs` — see the binding paragraph below.
|
|
190
|
+
10. `check:max-file-lines` — see the line-limit paragraph below.
|
|
191
|
+
|
|
192
|
+
Three things left the local chain in 11.8.0 and must not be "restored" as
|
|
193
|
+
habits: `check:python` (ruff already parses every file on every CI test leg),
|
|
194
|
+
`check:legacy-debt` (the Python test is authoritative), and the extension
|
|
195
|
+
tests (CI invokes them directly on the 3.11 + ubuntu leg). See
|
|
196
|
+
[CI_AND_RELEASE_GATES.md](CI_AND_RELEASE_GATES.md).
|
|
197
|
+
|
|
198
|
+
### Coverage floors
|
|
199
|
+
|
|
200
|
+
The floors are not symmetrical, and that is deliberate. Python
|
|
201
|
+
(`[tool.coverage.report] fail_under = 90` in `pyproject.toml`) is a
|
|
202
|
+
**line-coverage** floor; branch measurement is off. Run
|
|
203
|
+
`npm run test:coverage`. A red report is uncovered product lines in
|
|
204
|
+
`latticeai/` or `lattice_brain/` — add a unit test, do not lower the floor
|
|
205
|
+
and do not hide the line with `pragma: no cover` unless the exclusion is
|
|
206
|
+
reasoned. The frontend (`vitest.config.ts`) pins **100% on statements,
|
|
207
|
+
branches, functions, and lines** with `all: true`, so an untested new module
|
|
208
|
+
is in the denominator. Run `npm run test:frontend:coverage`. A file that
|
|
209
|
+
vanishes from the text reporter is fully covered; confirm with
|
|
210
|
+
`--coverage.reporter=json-summary`. `frontend/src/i18n/**`,
|
|
211
|
+
`frontend/src/api/openapi.ts`, and `frontend/src/main.tsx` are excluded on
|
|
212
|
+
purpose.
|
|
213
|
+
|
|
214
|
+
### Max-file-lines (1,000)
|
|
215
|
+
|
|
216
|
+
`scripts/check_max_file_lines.mjs` fails any git-tracked
|
|
217
|
+
`*.py *.ts *.tsx *.js *.mjs *.cjs *.css *.rs` over 1,000 lines, tests
|
|
218
|
+
included. It exists because a 10k-line CSS file and twenty-seven other
|
|
219
|
+
oversize modules landed before anyone noticed — long files burn review and
|
|
220
|
+
conflict on every feature. Split by cohesion, not at line 1,000. Exempt only
|
|
221
|
+
generated paths (`frontend/src/api/openapi.ts`, `static/app/`,
|
|
222
|
+
`static/vendor/`, `src-tauri/gen/`). A new exemption for a hand-written file
|
|
223
|
+
is not a fix.
|
|
224
|
+
|
|
225
|
+
### Clippy `-D warnings`
|
|
226
|
+
|
|
227
|
+
`npm run rust:lint` is `cargo fmt --all -- --check` then
|
|
228
|
+
`cargo clippy --workspace --all-targets -- -D warnings` inside `rust/`. CI
|
|
229
|
+
runs the same. The workspace no longer carries blanket `#![allow]`. Fix the
|
|
230
|
+
diagnostic at the source; do not re-allow it. Format drift is `cargo fmt`
|
|
231
|
+
in `rust/`.
|
|
232
|
+
|
|
233
|
+
### Docs gates
|
|
234
|
+
|
|
235
|
+
`npm run docs:check-links` is two scripts:
|
|
236
|
+
`scripts/check_markdown_links.mjs` (README plus one hop of README-linked
|
|
237
|
+
Markdown) and `scripts/check_doc_status.mjs` (every relative link under the
|
|
238
|
+
root canonical docs and `docs/**`). A red line is a broken relative path —
|
|
239
|
+
fix the href or put the file where the href says. Canonical docs (this one
|
|
240
|
+
included) must carry `Current release: **12.0.0 — …**` matching
|
|
241
|
+
`package.json`; do not bump that marker here ahead of the release lane.
|
|
242
|
+
`npm run docs:check-current` is the release-set version pin
|
|
243
|
+
([`scripts/check_current_release_docs.mjs`](../scripts/check_current_release_docs.mjs)).
|
|
244
|
+
Reference docs ([ROADMAP.md](ROADMAP.md), this file's siblings with
|
|
245
|
+
`Status: reference`) are not held to the version marker. Historical
|
|
246
|
+
changelog entries that mention old versions stay.
|
|
247
|
+
|
|
248
|
+
### Release-evidence binding
|
|
249
|
+
|
|
250
|
+
`scripts/check_release_evidence_bound.mjs` (lint member 9) checks that
|
|
251
|
+
`output/release/v12.0.0/SCREENSHOT_INDEX.md` still names the live
|
|
252
|
+
`static/app/asset-manifest.json` digest and the visual mock-server
|
|
253
|
+
fingerprint. It exists so a later `npm run build:assets` cannot ship
|
|
254
|
+
screenshots of an older UI, and so a mock-server edit cannot leave the
|
|
255
|
+
evidence describing a panel the tree no longer produces. Fix: run
|
|
256
|
+
`npm run build:assets` then `npm run release:evidence` (needs Playwright
|
|
257
|
+
Chromium and `ffmpeg`); the capture writes only to
|
|
258
|
+
`output/release/vX.Y.Z/`. `LTCAI_SKIP_RELEASE_EVIDENCE_BOUND=1` is the
|
|
259
|
+
capture script's own hatch, not a commit-time escape.
|
|
260
|
+
|
|
261
|
+
## House rules
|
|
262
|
+
|
|
263
|
+
**Honesty.** A stub is a stub. A capability that cannot complete surfaces
|
|
264
|
+
`unavailable` / `skipped` / `simulation` / `awaiting_approval` with a reason
|
|
265
|
+
— never a fabricated success, score, or record. A remaining `—` in
|
|
266
|
+
[FEATURE_STATUS.md](../FEATURE_STATUS.md) or
|
|
267
|
+
[SURFACE_PARITY.md](SURFACE_PARITY.md) states why it is a design boundary.
|
|
268
|
+
Do not write "Current" over a surface that 404s. See
|
|
269
|
+
[PROJECT_PRINCIPLES.md](../PROJECT_PRINCIPLES.md).
|
|
270
|
+
|
|
271
|
+
**Fail-closed verification is law.** An unverifiable agent outcome is
|
|
272
|
+
`NEEDS_REVIEW`, not success. An unknown permission case is a refusal. A
|
|
273
|
+
policy-less tool takes its most dangerous plausible class. The worker
|
|
274
|
+
allowlist answers `404` for everything it does not name. Graph scope errors
|
|
275
|
+
do not silently widen. Change-proposal approval whose base SHA no longer
|
|
276
|
+
matches is a **409**, never a merge and never a silent overwrite. Additive
|
|
277
|
+
creates may run with minimal friction; mutations and deletions of existing
|
|
278
|
+
user files are staged as review proposals (`change_proposal`) and applied
|
|
279
|
+
exactly as reviewed.
|
|
280
|
+
|
|
281
|
+
**Korean UX is the default.** Author product copy in Korean first; ship the
|
|
282
|
+
English pair in the same `registerCopy` table. `t()` falls back to
|
|
283
|
+
`COPY.ko`. The first-run `LanguageChooser` is on every onboarding step.
|
|
284
|
+
Do not leave an English literal on a path a Korean reader will see — the
|
|
285
|
+
i18n gates exist to catch that, and the remaining English API `detail`
|
|
286
|
+
strings are a named gap in [ROADMAP.md](ROADMAP.md), not a style.
|
|
287
|
+
|
|
288
|
+
**Tokens-only CSS.** React color lives in `frontend/src/styles/tokens.css`
|
|
289
|
+
and is consumed as `hsl(var(--token))`. No hex on a themed surface. Put a
|
|
290
|
+
new rule in the narrowest `frontend/src/styles/experience/` file. Do not
|
|
291
|
+
add another competing shell or composer rule to `styles.css`. No glass —
|
|
292
|
+
the 11.7.0 elevation ladder is the vocabulary.
|
|
293
|
+
|
|
294
|
+
**Workspace `null` = personal.** `DEFAULT_WORKSPACE_ID` is `"personal"`.
|
|
295
|
+
Reads treat a NULL or blank `workspace_id` as personal visibility.
|
|
296
|
+
Production `GraphWriter::open` stamps `"personal"` when a write omits a
|
|
297
|
+
workspace. A request that names two different workspaces (header vs.
|
|
298
|
+
query/body) is 403. Do not invent a second default string, and do not
|
|
299
|
+
treat NULL as "visible to every tenant".
|
|
300
|
+
|
|
301
|
+
## Documentation sync
|
|
146
302
|
|
|
147
303
|
For user-facing, API, runtime, release, or packaging changes, check:
|
|
148
304
|
|
|
149
|
-
-
|
|
150
|
-
-
|
|
151
|
-
-
|
|
152
|
-
-
|
|
153
|
-
-
|
|
154
|
-
-
|
|
155
|
-
-
|
|
156
|
-
|
|
305
|
+
- [README.md](../README.md)
|
|
306
|
+
- [ARCHITECTURE.md](../ARCHITECTURE.md)
|
|
307
|
+
- [FEATURE_STATUS.md](../FEATURE_STATUS.md)
|
|
308
|
+
- [RELEASE.md](../RELEASE.md)
|
|
309
|
+
- [CHANGELOG.md](CHANGELOG.md)
|
|
310
|
+
- [SECURITY.md](../SECURITY.md) when trust/security changes
|
|
311
|
+
- [vscode-extension/README.md](../vscode-extension/README.md) when editor
|
|
312
|
+
integration changes
|
|
313
|
+
- [LEGACY_COMPATIBILITY.md](LEGACY_COMPATIBILITY.md) when root compatibility
|
|
314
|
+
files change
|
|
315
|
+
- this file, when the contributor path or the map changes
|
|
316
|
+
- [ROADMAP.md](ROADMAP.md), when a named gap closes or a new honest leftover
|
|
317
|
+
appears
|
|
318
|
+
|
|
319
|
+
The release-docs lane owns README / ARCHITECTURE / FEATURE_STATUS version
|
|
320
|
+
bumps. Do not move this file's `Current release` marker off 12.0.0 ahead of
|
|
321
|
+
that lane.
|
|
157
322
|
|
|
158
323
|
Release/publish examples must use exact target-version filenames. Do not
|
|
159
324
|
document wildcard artifact upload commands.
|
|
160
325
|
|
|
161
|
-
For
|
|
326
|
+
For 12.0.0 release work, exact artifacts are:
|
|
327
|
+
|
|
328
|
+
- `dist/ltcai-12.0.0-py3-none-any.whl`
|
|
329
|
+
- `dist/ltcai-12.0.0.tar.gz`
|
|
330
|
+
- `ltcai-12.0.0.tgz`
|
|
331
|
+
- `dist/ltcai-12.0.0.vsix`
|
|
332
|
+
- `src-tauri/target/release/bundle/dmg/Lattice AI_12.0.0_aarch64.dmg`
|
|
162
333
|
|
|
163
|
-
- `
|
|
164
|
-
|
|
165
|
-
- `ltcai-9.9.0.tgz`
|
|
166
|
-
- `dist/ltcai-9.9.0.vsix`
|
|
167
|
-
- `src-tauri/target/release/bundle/dmg/Lattice AI_9.9.0_aarch64.dmg`
|
|
334
|
+
The dmg is ad-hoc signed (effectively unsigned); `npm run release:validate`
|
|
335
|
+
checks the names and presence, not a Developer ID signature.
|
package/docs/ENTERPRISE.md
CHANGED
|
@@ -22,7 +22,7 @@ boundary honest (Community is never crippled to upsell Enterprise).
|
|
|
22
22
|
## The extension seam
|
|
23
23
|
|
|
24
24
|
The seam moved to Rust with the product server in 11.6.0 and now lives in
|
|
25
|
-
[`rust/lattice-platform/src/admin/enterprise.rs`](../rust/lattice-platform/src/admin/enterprise.rs):
|
|
25
|
+
[`rust/lattice-platform/src/adminops/admin/enterprise.rs`](../rust/lattice-platform/src/adminops/admin/enterprise.rs):
|
|
26
26
|
|
|
27
27
|
- `Edition` — `community` (default) or `enterprise`.
|
|
28
28
|
- `EnterpriseCapability` — the enum of reserved capabilities (below).
|
|
@@ -26,14 +26,18 @@ Removed layers stay listed in `legacy_compatibility.REMOVED_SHIMS` and in the
|
|
|
26
26
|
|
|
27
27
|
## Legacy Debt Gate
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
**One** gate keeps the debt paid down:
|
|
30
30
|
|
|
31
|
-
- `scripts/check_legacy_debt.mjs` (part of `npm run lint`) — fails if a
|
|
32
|
-
disallowed root-level Python module reappears, or if any source tree imports
|
|
33
|
-
a removed root shim.
|
|
34
31
|
- `tests/unit/test_legacy_root_shims.py` — asserts removed shims stay
|
|
35
|
-
unimportable
|
|
36
|
-
|
|
32
|
+
unimportable and canonical replacements import.
|
|
33
|
+
|
|
34
|
+
There used to be two. `scripts/check_legacy_debt.mjs` stated the same rule in
|
|
35
|
+
JavaScript as part of `npm run lint`, and by 11.8.0 the two implementations had
|
|
36
|
+
drifted apart — at which point having both was worse than having one, because
|
|
37
|
+
neither could be trusted as the answer. The Python test is authoritative and the
|
|
38
|
+
mjs mirror was deleted. `latticeai.core.legacy_compatibility` went with the
|
|
39
|
+
platform code in 11.6.0; the registry it held described modules that no longer
|
|
40
|
+
exist to shim.
|
|
37
41
|
|
|
38
42
|
## Root Module Map (removed in 9.9.1)
|
|
39
43
|
|
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
The Multi-Agent Runtime is the **orchestration layer** introduced in v2.0.0 and
|
|
4
4
|
operationalized in v2.2.0. It sits
|
|
5
5
|
*above* the single-agent state machine, which since 11.6.0 is the Rust loop
|
|
6
|
-
orchestrator ([`lattice_agent::agentloop`](../rust/lattice-agent/src/agentloop/mod.rs))
|
|
6
|
+
orchestrator ([`lattice_agent::agentloop`](../rust/lattice-agent/src/kernel/agentloop/mod.rs))
|
|
7
7
|
and coordinates a pipeline of named **roles** that hand off work to one another,
|
|
8
8
|
retry on a failing review, and emit a fully observable, replayable timeline.
|
|
9
9
|
|
|
10
|
-
- **Source of truth:** `rust/lattice-platform/src/agents.rs` (the orchestration
|
|
11
|
-
routes) over `rust/lattice-agent/src/agentloop/` (the state machine)
|
|
10
|
+
- **Source of truth:** `rust/lattice-platform/src/toolsurface/agents/mod.rs` (the orchestration
|
|
11
|
+
routes) over `rust/lattice-agent/src/kernel/agentloop/` (the state machine)
|
|
12
12
|
- **HTTP surface:** the `agents` family, mounted by `lattice-platform`
|
|
13
|
-
- **Persistence:** `rust/lattice-platform/src/review_queue.rs` — the same
|
|
13
|
+
- **Persistence:** `rust/lattice-platform/src/governance/review_queue.rs` — the same
|
|
14
14
|
`workspace_os.json` document the Review Center reads
|
|
15
15
|
|
|
16
16
|
> **Moved in 11.6.0.** The Python modules this page used to name
|
package/docs/ONBOARDING.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Lattice AI Onboarding
|
|
2
2
|
|
|
3
|
-
Current release: **
|
|
3
|
+
Current release: **12.0.0 — Open House**.
|
|
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
|
|
@@ -10,8 +10,12 @@ read the docs first.
|
|
|
10
10
|
## Five-Minute Flow
|
|
11
11
|
|
|
12
12
|
1. Wake the Brain and confirm the local owner profile.
|
|
13
|
-
2. Let Lattice inspect local model/runtime readiness
|
|
14
|
-
|
|
13
|
+
2. Let Lattice inspect local model/runtime readiness (`/setup/scan` is a
|
|
14
|
+
real probe). Since 12.0.0 a listed brew/pip/uv item can be installed
|
|
15
|
+
from here, one item at a time and only when the user says so — the
|
|
16
|
+
default is still to show the command rather than run it.
|
|
17
|
+
3. Pick the recommended Brain voice (`/models/recommendations` probes RAM
|
|
18
|
+
and the worker catalog) or skip model loading.
|
|
15
19
|
4. Add one source: upload a file, choose and scan a folder, save a note, or
|
|
16
20
|
capture a browser/source event.
|
|
17
21
|
5. Ask one grounded question and inspect the answer proof.
|
|
@@ -30,7 +34,15 @@ read the docs first.
|
|
|
30
34
|
- Empty states suggest one concrete next action without claiming proof that does
|
|
31
35
|
not exist yet.
|
|
32
36
|
- Core-service failures show an unavailable/error state and recovery guidance;
|
|
33
|
-
they are never presented as an empty or healthy Brain.
|
|
37
|
+
they are never presented as an empty or healthy Brain. Since 12.0.0 every
|
|
38
|
+
route and every heavy panel sits inside an error boundary with a 다시 시도
|
|
39
|
+
action, so one failing panel costs its own card rather than the screen.
|
|
40
|
+
- The first source can be added on any model the machine can hold: the agent
|
|
41
|
+
profile is measured on load, and a model that cannot emit a tool call is
|
|
42
|
+
guided through numbered choices instead of failing the run.
|
|
43
|
+
- Re-scanning a folder that has not changed is nearly free, so re-indexing is
|
|
44
|
+
a safe habit rather than a cost. A file deleted from disk keeps its memory
|
|
45
|
+
until the user confirms the 「삭제된 파일 정리」 action.
|
|
34
46
|
- Upload, note, browser, and message ingestion all converge through the unified
|
|
35
47
|
ingestion pipeline when it is available.
|
|
36
48
|
- Workspace-scoped content must not leak or overwrite another workspace's graph
|
package/docs/OPERATIONS.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Lattice AI — Operations Guide (
|
|
1
|
+
# Lattice AI — Operations Guide (v12.0.0)
|
|
2
2
|
|
|
3
3
|
> **Status: canonical** — kept in sync with the current release. Storage layout
|
|
4
4
|
> below reflects the SQLite live Brain store and workspace scoping, not the
|
|
@@ -29,6 +29,19 @@ tar -czf ltcai-backup-$(date +%Y%m%d).tar.gz ~/.ltcai ~/ltcai-agent
|
|
|
29
29
|
tar -xzf ltcai-backup-YYYYMMDD.tar.gz -C ~
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
+
인앱 복원(`.latticebrain` / `VACUUM INTO` 스냅샷)은 원자적이고, **v12.0.0
|
|
33
|
+
부터 즉시 반영됩니다 — 복원 뒤 재시작이 필요 없습니다.** 스토어가
|
|
34
|
+
세대(generation) 에폭을 들고 있어서, 복원이 에폭을 올리면 이전 세대에서
|
|
35
|
+
열린 풀 커넥션은 다음 체크아웃에서 낡은 것으로 판정되어 닫히고, 그다음
|
|
36
|
+
읽기는 복원된 바이트를 봅니다. 11.9.0까지의 완화책이던 "복원 후 재시작"
|
|
37
|
+
절차는 더 이상 필요하지 않습니다.
|
|
38
|
+
|
|
39
|
+
삭제된 파일 정리는 별개의 확인된 동작입니다: `POST
|
|
40
|
+
/api/ingestion/folder/prune`가 `confirm` 없이는 dry-run(무엇이 지워질지와
|
|
41
|
+
노드/엣지/청크/벡터 수)이고, `confirm`이 있을 때만 문서 서브트리를
|
|
42
|
+
`delete_document_tree`로 제거합니다. 어느 경로도 디스크의 파일을 지우지
|
|
43
|
+
않습니다.
|
|
44
|
+
|
|
32
45
|
### 2.3 히스토리만 초기화
|
|
33
46
|
```bash
|
|
34
47
|
rm ~/.ltcai/history.json
|
package/docs/PERMISSION_MODE.md
CHANGED
|
@@ -97,18 +97,23 @@ before routers are mounted would otherwise pin the store to the fallback
|
|
|
97
97
|
|
|
98
98
|
## Code map
|
|
99
99
|
|
|
100
|
+
The dial is native. v11.6.0 moved the agent loop into `lattice-agent` and the
|
|
101
|
+
routes into `lattice-platform`; v11.8.0 deleted the last Python module that
|
|
102
|
+
still carried a copy of the gate helpers (`latticeai/core/agent_permission.py`,
|
|
103
|
+
whose only readers were already ported).
|
|
104
|
+
|
|
100
105
|
| Module | Role |
|
|
101
106
|
|--------|------|
|
|
102
|
-
| `
|
|
103
|
-
| `
|
|
104
|
-
| `
|
|
107
|
+
| `rust/lattice-agent/src/mode.rs` | Pure decision table (port of `latticeai.core.permission_mode`) |
|
|
108
|
+
| `rust/lattice-agent/src/permission.rs` | Plan/tool gate helpers — the ordered block-reason chain |
|
|
109
|
+
| `rust/lattice-agent/src/breaker.rs` | Mode-invariant circuit breakers |
|
|
110
|
+
| `rust/lattice-agent/src/agentloop/gates.rs` | The gates one executor step passes, in the order that decides it |
|
|
111
|
+
| `rust/lattice-agent/src/agentloop/planning.rs` | The plan gate |
|
|
112
|
+
| `rust/lattice-platform/src/permission_mode.rs` | HTTP routes + persistence (`permission_mode.json`, atomic replace) |
|
|
113
|
+
| `rust/lattice-auth/src/policy.rs` | The tool policy table the gates read |
|
|
105
114
|
| `frontend/src/components/PermissionModePanel.tsx` | Settings selector |
|
|
106
|
-
| `
|
|
107
|
-
| `latticeai/
|
|
108
|
-
| `latticeai/runtime/chat_wiring.py` | Agent runtime injection |
|
|
109
|
-
| `latticeai/runtime/router_registration.py` | HTTP mount |
|
|
110
|
-
| `latticeai/services/tool_dispatch.py` | `enforce_policy` + `build_agent_runtime` |
|
|
111
|
-
| `latticeai/api/permission_mode.py` | HTTP routes |
|
|
115
|
+
| `frontend/src/lib/permissionCopy.ts` | The plain-language wording for each mode |
|
|
116
|
+
| `latticeai/core/permission_mode.py` | The worker's own `is_circuit_breaker`, asked by `POST /agent/tool` — the mode-invariant refusal holds on the executing side too, not only at the gate that dispatched |
|
|
112
117
|
|
|
113
118
|
## AGENTS.md note
|
|
114
119
|
|
|
@@ -5,7 +5,7 @@ Realtime Collaboration is the subsystem that gives a Lattice AI workspace a live
|
|
|
5
5
|
workspace-scoped execution observability for agents, handoffs, reviews,
|
|
6
6
|
workflows, plugins, retries, and failures. It is delivered over Server-Sent
|
|
7
7
|
Events (SSE) by an in-process pub/sub bus, the
|
|
8
|
-
[`RealtimeBus`](../rust/lattice-platform/src/realtime.rs), native since 11.6.0.
|
|
8
|
+
[`RealtimeBus`](../rust/lattice-platform/src/workspaceos/realtime.rs), native since 11.6.0.
|
|
9
9
|
|
|
10
10
|
The design goal is to surface "what is happening in the workspace right now"
|
|
11
11
|
(workspaces created, graphs indexed, agents and workflows run, plugins enabled,
|