ltcai 9.5.0 → 9.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +57 -43
  2. package/docs/CHANGELOG.md +32 -0
  3. package/docs/COMMUNITY_AND_PLUGINS.md +2 -2
  4. package/docs/DEVELOPMENT.md +8 -8
  5. package/docs/LEGACY_COMPATIBILITY.md +1 -1
  6. package/docs/ONBOARDING.md +2 -2
  7. package/docs/OPERATIONS.md +1 -1
  8. package/docs/TRUST_MODEL.md +1 -1
  9. package/docs/WHY_LATTICE.md +1 -1
  10. package/docs/kg-schema.md +1 -1
  11. package/docs/mcp-tools.md +1 -1
  12. package/lattice_brain/__init__.py +1 -1
  13. package/lattice_brain/runtime/multi_agent.py +1 -1
  14. package/latticeai/__init__.py +1 -1
  15. package/latticeai/api/change_proposals.py +60 -0
  16. package/latticeai/api/chat_agent_http.py +2 -0
  17. package/latticeai/app_factory.py +20 -0
  18. package/latticeai/cli/entrypoint.py +3 -1
  19. package/latticeai/core/agent.py +127 -13
  20. package/latticeai/core/agent_eval.py +260 -0
  21. package/latticeai/core/agent_trace.py +104 -0
  22. package/latticeai/core/legacy_compatibility.py +1 -1
  23. package/latticeai/core/marketplace.py +1 -1
  24. package/latticeai/core/tool_governor.py +101 -0
  25. package/latticeai/core/workspace_os.py +1 -1
  26. package/latticeai/services/architecture_readiness.py +1 -1
  27. package/latticeai/services/change_proposals.py +270 -0
  28. package/latticeai/services/product_readiness.py +1 -1
  29. package/latticeai/services/review_queue.py +4 -1
  30. package/latticeai/tools/__init__.py +6 -1
  31. package/package.json +1 -1
  32. package/scripts/agent_eval.py +46 -0
  33. package/scripts/check_current_release_docs.mjs +2 -1
  34. package/src-tauri/Cargo.lock +1 -1
  35. package/src-tauri/Cargo.toml +1 -1
  36. package/src-tauri/tauri.conf.json +1 -1
  37. package/static/app/asset-manifest.json +11 -11
  38. package/static/app/assets/{Act-Cdfqx4wN.js → Act-BkOEmwBi.js} +1 -1
  39. package/static/app/assets/{Brain-w_tAuyg6.js → Brain-C9ITUsQ_.js} +1 -1
  40. package/static/app/assets/{Capture-iJwi9LmS.js → Capture-C-ppTeud.js} +1 -1
  41. package/static/app/assets/{Library-Do-jjhzi.js → Library-CGQbgWTu.js} +1 -1
  42. package/static/app/assets/{System-DFg_q3E6.js → System-djmj0n2_.js} +1 -1
  43. package/static/app/assets/{index-BN6HIWVC.css → index-85wQvEie.css} +1 -1
  44. package/static/app/assets/index-AF0-4XVv.js +18 -0
  45. package/static/app/assets/{primitives-ZTUlU7pR.js → primitives-jbb2qv4Q.js} +1 -1
  46. package/static/app/assets/{textarea-CMfhqPhE.js → textarea-CFoo0OxJ.js} +1 -1
  47. package/static/app/index.html +2 -2
  48. package/static/sw.js +1 -1
  49. package/static/app/assets/index-aJuRi-Xo.js +0 -17
package/README.md CHANGED
@@ -1,9 +1,17 @@
1
1
  # Lattice AI
2
2
 
3
- **Lattice AI 9.5.0 is the local-first Digital Brain platform. The Command Center puts everything one keystroke away: a Cmd+K palette that searches knowledge, past conversations, automations, and app pages in one query, and a daily briefing that condenses recent knowledge, automation state, pending reviews, Brain health, and suggested next steps into one glance with one-click quick actions.**
3
+ **Lattice AI 9.6.0 is the local-first Digital Brain platform. The Trusted Agent Loop makes autonomous work transparent and git-like: the reasoning loop reports every model call, format repair, and tool outcome; a deterministic evaluation harness gates every release on weak-model robustness; and change governance is proposal-first creating new files is frictionless while edits and deletions of existing content become reviewable proposals you approve or reject before anything changes.**
4
4
 
5
5
  **Lattice AI는 모델이 바뀌어도 내 지식과 맥락을 보존하는 로컬 우선 AI 브레인입니다.**
6
6
 
7
+ > The 9.6.0 release engineers trust into the agent loop: a structured
8
+ > LoopTrace makes every run observable (llm calls, parse recoveries, format
9
+ > repairs, corrections, tool outcomes — returned as `loop` in the agent API),
10
+ > weak-model tolerance gains python-literal repair and escalating format
11
+ > corrections, a deterministic agent evaluation harness gates CI, and a
12
+ > central change governor stages edits/deletions of existing files as review
13
+ > proposals (`/api/proposals`) applied exactly as reviewed — while new-file
14
+ > creation now runs without approval friction.
7
15
  > The 9.5.0 release adds the Command Center: a deterministic, local
8
16
  > `/api/command` surface serving a daily briefing (recent knowledge,
9
17
  > conversation activity, automation state, pending reviews, health snapshot,
@@ -108,11 +116,11 @@ You need Lattice AI when:
108
116
  The screenshots below are the latest checked-in visual evidence captures. They
109
117
  keep the first-run Brain flow, memory graph, source capture, model library,
110
118
  system view, admin console, and review center visible as release gates while
111
- 9.5.0 puts the whole Brain one keystroke away: the Cmd+K Command Palette
112
- searches knowledge, conversations, automations, and pages in one query, and
113
- Today's Briefing condenses the Brain's state into one glance with one-click
114
- next steps. The captures below are the checked-in 9.5.0 visual release
115
- evidence for that product flow.
119
+ 9.6.0 makes autonomous work trustworthy: agents create new things freely,
120
+ but every change to existing content becomes a reviewable proposal with a
121
+ diff, and the reasoning loop itself is observable and regression-gated. The
122
+ captures below are the checked-in 9.6.0 visual release evidence for that
123
+ product flow.
116
124
 
117
125
  ### 1. Wake Brain
118
126
 
@@ -124,21 +132,21 @@ confirm owner, check the computer, choose the Brain voice.
124
132
  Choose the owner of the Brain. The profile is not a SaaS account by default; it
125
133
  is the local identity for the knowledge you keep.
126
134
 
127
- ![Login](output/release/v9.5.0/screenshots/01-login.png)
135
+ ![Login](output/release/v9.6.0/screenshots/01-login.png)
128
136
 
129
137
  ### 3. Recommended Models
130
138
 
131
139
  Start with a short list: safest recommendation, faster model, stronger model.
132
140
  Advanced details stay available without overwhelming first-time users.
133
141
 
134
- ![Recommended Models](output/release/v9.5.0/screenshots/02-recommended-models.png)
142
+ ![Recommended Models](output/release/v9.6.0/screenshots/02-recommended-models.png)
135
143
 
136
144
  ### 4. Install And Load
137
145
 
138
146
  Download and load only after consent. Lattice explains model size, local
139
147
  execution, and network use before work starts.
140
148
 
141
- ![Install and Load](output/release/v9.5.0/screenshots/03-install-load-progress.png)
149
+ ![Install and Load](output/release/v9.6.0/screenshots/03-install-load-progress.png)
142
150
 
143
151
  ### 5. Brain Chat
144
152
 
@@ -150,14 +158,14 @@ and its visible life signal follow real listening, recall, synthesis, and action
150
158
  state. Detailed memory rings, provenance, conversation history, and
151
159
  model/runtime proof open as overlays only when requested.
152
160
 
153
- ![One-viewport Living Brain Home](output/release/v9.5.0/screenshots/04-brain-chat-home.png)
161
+ ![One-viewport Living Brain Home](output/release/v9.6.0/screenshots/04-brain-chat-home.png)
154
162
 
155
163
  ### 6. Review Center
156
164
 
157
165
  Automation results are staged for review before they become durable decisions.
158
166
  Snooze, unsnooze, run now, approve, and dismiss actions stay explicit.
159
167
 
160
- ![Review Center](output/release/v9.5.0/screenshots/12-review-center.png)
168
+ ![Review Center](output/release/v9.6.0/screenshots/12-review-center.png)
161
169
 
162
170
  ## Brain Depths
163
171
 
@@ -173,10 +181,10 @@ The user travels inward from everyday memory to deeper structure:
173
181
 
174
182
  Walkthrough:
175
183
 
176
- ![v9.5.0 Living Brain walkthrough](output/release/v9.5.0/gifs/v9.5.0-living-brain-walkthrough.gif)
184
+ ![v9.6.0 Living Brain walkthrough](output/release/v9.6.0/gifs/v9.6.0-living-brain-walkthrough.gif)
177
185
 
178
186
  Screenshot index and capture notes:
179
- [output/release/v9.5.0/SCREENSHOT_INDEX.md](output/release/v9.5.0/SCREENSHOT_INDEX.md)
187
+ [output/release/v9.6.0/SCREENSHOT_INDEX.md](output/release/v9.6.0/SCREENSHOT_INDEX.md)
180
188
 
181
189
  ## Install
182
190
 
@@ -261,45 +269,50 @@ See [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) for developer workflow details.
261
269
 
262
270
  ## Current Release
263
271
 
264
- The current release is **9.5.0 — Command Center**:
265
-
266
- - A new `CommandCenterService` (`/api/command/briefing`, `/api/command/search`)
267
- aggregates every Brain surface read-only and deterministically: recent
268
- knowledge from the scoped graph, conversation activity, automation
269
- enable/draft counts, pending review items, a Brain-health snapshot, and the
270
- top automation suggestions each section degrades independently when a
271
- backend is unavailable.
272
- - State-derived quick actions with stable ids ("N items waiting for review",
273
- "enable your draft automations", "connect a knowledge folder") give the UI
274
- one-click jumps that always reflect the actual product state.
275
- - Universal search groups results across knowledge nodes (scoped keyword
276
- search), the user's own conversations (deduped per conversation, newest
277
- first), and installed automations all scoped to the requesting user and
278
- workspace.
279
- - The frontend gains a Cmd+K Command Palette (grouped results, keyboard
280
- navigation, page jumps, fully ko/en localized) and a Today's Briefing panel
281
- on the Brain home with stat chips, recent knowledge, and quick actions.
282
- - Everything is read-only, local, and model-free: no model calls, no writes,
283
- no external actions.
284
-
285
- Expected artifacts for 9.5.0 release must use exact filenames:
286
-
287
- - `dist/ltcai-9.5.0-py3-none-any.whl`
288
- - `dist/ltcai-9.5.0.tar.gz`
289
- - `ltcai-9.5.0.tgz`
290
- - `dist/ltcai-9.5.0.vsix`
291
- - `src-tauri/target/release/bundle/dmg/Lattice AI_9.5.0_aarch64.dmg`
272
+ The current release is **9.6.0 — Trusted Agent Loop**:
273
+
274
+ - The single-agent reasoning loop is fully observable: a structured
275
+ `LoopTrace` records every llm call, parse error (recovered or not), format
276
+ repair, correction, tool outcome, retry, and rollback, and its summary is
277
+ returned as `loop` with every agent API response.
278
+ - Weak-model robustness is stronger and measured: the action parser now also
279
+ repairs Python-literal dicts (single quotes, True/False/None), repairs are
280
+ reported by name, and a second formatting slip escalates the correction
281
+ with the exact list of valid tools.
282
+ - A deterministic agent evaluation harness (`scripts/agent_eval.py`, CI
283
+ gate) drives the real state machine through scripted scenarios — happy
284
+ path, weak-model format gauntlet, correction escalation, destructive
285
+ block, loop detection, critic retry, unrecoverable garbage and must stay
286
+ at 100% scenario pass.
287
+ - Change governance is proposal-first (`latticeai/core/tool_governor.py`):
288
+ additive creates run with minimal friction, while agent edits/deletions of
289
+ existing files are staged as review proposals with a unified diff and a
290
+ small/large tier, listed at `GET /api/proposals`, applied exactly as
291
+ reviewed on approve, discarded on reject. The Brain home shows a
292
+ "변경 제안 / Change proposals" panel with diff previews and one-click
293
+ approve/reject.
294
+ - Housekeeping: Ruff per-file lint ignores trimmed from 9 entries to 3,
295
+ AGENTS.md now carries a machine-checked current-release marker inside the
296
+ docs gate, and the review queue gained the `change_proposal` source.
297
+
298
+ Expected artifacts for 9.6.0 release must use exact filenames:
299
+
300
+ - `dist/ltcai-9.6.0-py3-none-any.whl`
301
+ - `dist/ltcai-9.6.0.tar.gz`
302
+ - `ltcai-9.6.0.tgz`
303
+ - `dist/ltcai-9.6.0.vsix`
304
+ - `src-tauri/target/release/bundle/dmg/Lattice AI_9.6.0_aarch64.dmg`
292
305
 
293
306
  Do not use wildcard artifact uploads. Package registry publishing remains owner-run.
294
307
 
295
308
  See [docs/ROADMAP_RECOMMENDATIONS.md](docs/ROADMAP_RECOMMENDATIONS.md) for the
296
- strategic roadmap slices applied through 9.5.0 and the follow-up tracks.
309
+ strategic roadmap slices applied through 9.6.0 and the follow-up tracks.
297
310
 
298
311
  ## Known Limitations
299
312
 
300
313
  - External package registries are owner-published and can lag behind GitHub.
301
314
  - PostgreSQL/pgvector is optional scale/migration tooling. SQLite remains the
302
- live local Brain store in 9.5.0.
315
+ live local Brain store in 9.6.0.
303
316
  - Docker, model downloads, cloud model calls, Telegram, Brain Network, and update
304
317
  checks require explicit user action.
305
318
  - Conversation does not fabricate answers when no model is loaded.
@@ -311,6 +324,7 @@ strategic roadmap slices applied through 9.5.0 and the follow-up tracks.
311
324
 
312
325
  | Version | Theme |
313
326
  | --- | --- |
327
+ | 9.6.0 | Trusted Agent Loop: observable agent reasoning (LoopTrace + loop API payload), python-literal/fence/think weak-model repairs with escalating corrections, a deterministic CI agent-eval harness, and proposal-first change governance where edits/deletions of existing files become reviewable diffs |
314
328
  | 9.5.0 | Command Center: a Cmd+K palette searching knowledge, conversations, automations, and pages in one query, plus a daily briefing with Brain state at a glance and state-derived one-click quick actions |
315
329
  | 9.4.0 | Question-Driven Everyday Automation: the Brain mines recurring user questions and connected knowledge folders into one-click, consent-first automation suggestions installed as review-gated drafts |
316
330
  | 9.3.0 | Proactive Brain Intelligence: the Brain diagnoses its own health, surfaces contradictions and stale knowledge, proposes consent-first duplicate consolidation, and recalls with hybrid lexical+semantic evidence behind an honest quality gate |
package/docs/CHANGELOG.md CHANGED
@@ -4,6 +4,38 @@ The top entry is either the current unreleased main-branch work or the current
4
4
  release line. Older entries are historical and may describe behavior as it
5
5
  existed at that release.
6
6
 
7
+ ## [9.6.0] - 2026-07-20
8
+
9
+ ### Added
10
+ - Added `latticeai/core/agent_trace.py` (`LoopTrace`): typed observability
11
+ for the single-agent reasoning loop, returned as `loop` with every agent
12
+ API response.
13
+ - Added `latticeai/core/agent_eval.py` + `scripts/agent_eval.py`: a
14
+ deterministic scripted-model evaluation harness over the real agent state
15
+ machine, wired into CI as a release gate.
16
+ - Added `latticeai/core/tool_governor.py` and
17
+ `latticeai/services/change_proposals.py` + `/api/proposals` router:
18
+ central read/additive/mutation/destructive classification with
19
+ proposal-first governance — edits/deletions of existing files are staged
20
+ as review-queue proposals (source `change_proposal`) with unified diffs
21
+ and applied exactly as reviewed on approval.
22
+ - Added the "변경 제안 / Change proposals" Brain home panel with diff
23
+ previews and one-click approve/reject.
24
+
25
+ ### Changed
26
+ - The action parser tolerates Python-literal dicts and reports every repair
27
+ by name; repeated formatting slips escalate the correction with the valid
28
+ tool list.
29
+ - Additive file creates in the agent loop run without plan-approval
30
+ friction; plan approval no longer hard-blocks governor-managed tools.
31
+ - Ruff per-file lint ignores trimmed from 9 entries to 3.
32
+
33
+ ### Security
34
+ - Mutations and deletions of existing workspace files by the agent can no
35
+ longer apply silently: they stage as reviewable proposals, and approve
36
+ applies the exact reviewed content with full audit events.
37
+ - AGENTS.md is now inside the machine-checked release documentation gate.
38
+
7
39
  ## [9.5.0] - 2026-07-20
8
40
 
9
41
  ### Added
@@ -1,13 +1,13 @@
1
1
  # Community And Plugins
2
2
 
3
- Current release: **9.5.0 — Command Center**.
3
+ Current release: **9.6.0 — Trusted Agent Loop**.
4
4
 
5
5
  LatticeAI defines the path from a strong local-first framework (8.4.0
6
6
  action-aware baseline, 8.5.0 registry+DI hardening, 8.6.0 capture/navigation
7
7
  reliability, 8.7.0 runtime-state hygiene, 8.8.0 Brain Core extraction
8
8
  readiness, 8.9.0 scoped Tool API hardening, 9.0.0 cleanup closure, 9.1.0
9
9
  fail-closed review completion, 9.2.0 model-agnostic file generation, 9.3.0
10
- proactive Brain intelligence, 9.4.0 question-driven everyday automation, and 9.5.0 Command Center)
10
+ proactive Brain intelligence, 9.4.0 question-driven everyday automation, 9.5.0 Command Center, and 9.6.0 Trusted Agent Loop)
11
11
  to a product ecosystem. The
12
12
  immediate goal is small and practical: make it clear how
13
13
  contributors can extend the Brain without weakening local-first trust,
@@ -1,10 +1,10 @@
1
1
  # Lattice AI Development
2
2
 
3
- Current release: **9.5.0 — Command Center**.
3
+ Current release: **9.6.0 — Trusted Agent Loop**.
4
4
 
5
5
  This document is for contributors working on the local-first Digital Brain
6
6
  codebase. Product positioning and quick start stay in `README.md`; release
7
- history is intentionally limited to 8.0.0-9.5.0 in `docs/CHANGELOG.md` and
7
+ history is intentionally limited to 8.0.0-9.6.0 in `docs/CHANGELOG.md` and
8
8
  `RELEASE.md`.
9
9
 
10
10
  ## Product Contract
@@ -153,10 +153,10 @@ For user-facing, API, runtime, release, or packaging changes, check:
153
153
  Release/publish examples must use exact target-version filenames. Do not
154
154
  document wildcard artifact upload commands.
155
155
 
156
- For 9.5.0 release work, exact artifacts are:
156
+ For 9.6.0 release work, exact artifacts are:
157
157
 
158
- - `dist/ltcai-9.5.0-py3-none-any.whl`
159
- - `dist/ltcai-9.5.0.tar.gz`
160
- - `ltcai-9.5.0.tgz`
161
- - `dist/ltcai-9.5.0.vsix`
162
- - `src-tauri/target/release/bundle/dmg/Lattice AI_9.5.0_aarch64.dmg`
158
+ - `dist/ltcai-9.6.0-py3-none-any.whl`
159
+ - `dist/ltcai-9.6.0.tar.gz`
160
+ - `ltcai-9.6.0.tgz`
161
+ - `dist/ltcai-9.6.0.vsix`
162
+ - `src-tauri/target/release/bundle/dmg/Lattice AI_9.6.0_aarch64.dmg`
@@ -1,6 +1,6 @@
1
1
  # Legacy Compatibility Map
2
2
 
3
- Current target: **9.5.0 — Command Center**.
3
+ Current target: **9.6.0 — Trusted Agent Loop**.
4
4
 
5
5
  Lattice AI is moving toward a smaller, modular architecture centered on
6
6
  `lattice_brain`, `latticeai.services`, `latticeai.api`, and `latticeai.runtime`.
@@ -1,6 +1,6 @@
1
1
  # Lattice AI Onboarding
2
2
 
3
- Current release: **9.5.0 — Command Center**.
3
+ Current release: **9.6.0 — Trusted Agent Loop**.
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
@@ -40,7 +40,7 @@ read the docs first.
40
40
 
41
41
  ## Release Gate
42
42
 
43
- 9.5.0 treats onboarding as a release gate, not marketing copy. The current
43
+ 9.6.0 treats onboarding as a release gate, not marketing copy. The current
44
44
  machine-checkable product readiness report requires this five-minute contract,
45
45
  the Brain Home surface, setup helpers, graph ingestion tests, and exact release
46
46
  artifact documentation before the release can be called complete.
@@ -1,4 +1,4 @@
1
- # Lattice AI — Operations Guide (v9.5.0)
1
+ # Lattice AI — Operations Guide (v9.6.0)
2
2
 
3
3
  ## 1. 데이터 파일 위치
4
4
 
@@ -1,6 +1,6 @@
1
1
  # Lattice AI Trust Model
2
2
 
3
- Current release: **9.5.0 — Command Center**.
3
+ Current release: **9.6.0 — Trusted Agent Loop**.
4
4
 
5
5
  Lattice AI is local-first, explicit about external communication, and honest
6
6
  when a capability is unavailable.
@@ -1,6 +1,6 @@
1
1
  # Why Lattice AI Exists
2
2
 
3
- Current release: **9.5.0 — Command Center**.
3
+ Current release: **9.6.0 — Trusted Agent Loop**.
4
4
 
5
5
  **Lattice AI is a local-first Digital Brain that keeps your knowledge durable
6
6
  across any AI model.**
package/docs/kg-schema.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Knowledge Graph Schema
2
2
 
3
- Current release: **9.5.0 — Command Center**.
3
+ Current release: **9.6.0 — Trusted Agent Loop**.
4
4
 
5
5
  명세 출처: `lattice_ai_full_spec.pptx` 슬라이드 20·21·22
6
6
  구현: `kg_schema.py`
package/docs/mcp-tools.md CHANGED
@@ -1,4 +1,4 @@
1
- # MCP 도구 카탈로그 (v9.5.0)
1
+ # MCP 도구 카탈로그 (v9.6.0)
2
2
 
3
3
  Lattice AI는 MCP(Model Context Protocol) 서버로 동작하여 Claude Desktop, Cursor 등에서 직접 도구를 사용할 수 있습니다.
4
4
 
@@ -26,7 +26,7 @@ from .storage import (
26
26
  storage_from_env,
27
27
  )
28
28
 
29
- __version__ = "9.5.0"
29
+ __version__ = "9.6.0"
30
30
 
31
31
  __all__ = [
32
32
  "AgentRuntime",
@@ -21,7 +21,7 @@ from .contracts import multi_agent_contract
21
21
  from ..utils import now_iso as _now
22
22
 
23
23
 
24
- MULTI_AGENT_VERSION = "9.5.0"
24
+ MULTI_AGENT_VERSION = "9.6.0"
25
25
 
26
26
  AGENT_ROLES = ("researcher", "planner", "executor", "reviewer", "release")
27
27
  CORE_PIPELINE = ("planner", "executor", "reviewer")
@@ -1,3 +1,3 @@
1
1
  """Lattice AI - modular server package."""
2
2
 
3
- __version__ = "9.5.0"
3
+ __version__ = "9.6.0"
@@ -0,0 +1,60 @@
1
+ """Change proposal API router (v9.6.0).
2
+
3
+ Read/approve/reject surface over
4
+ :class:`~latticeai.services.change_proposals.ChangeProposalService`. The
5
+ items live in the shared review queue (source ``change_proposal``), so the
6
+ Act review center shows them too; this router adds the proposal-specific
7
+ semantics: **approve applies the staged content exactly as reviewed**,
8
+ reject discards it, and nothing touches disk while a proposal is pending.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ from typing import Callable, Optional
14
+
15
+ from fastapi import APIRouter, HTTPException, Request
16
+
17
+ from latticeai.services.change_proposals import ChangeProposalService
18
+
19
+
20
+ def create_change_proposals_router(
21
+ *,
22
+ service: ChangeProposalService,
23
+ require_user: Callable[[Request], str],
24
+ gate_read: Callable[[Request], Optional[str]],
25
+ gate_write: Callable[[Request], Optional[str]],
26
+ ) -> APIRouter:
27
+ router = APIRouter()
28
+
29
+ @router.get("/api/proposals")
30
+ async def list_proposals(request: Request):
31
+ user = require_user(request)
32
+ scope = gate_read(request)
33
+ return service.pending(user_email=user, workspace_id=scope)
34
+
35
+ @router.post("/api/proposals/{item_id}/approve")
36
+ async def approve_proposal(item_id: str, request: Request):
37
+ user = require_user(request)
38
+ scope = gate_write(request)
39
+ try:
40
+ return service.approve_and_apply(
41
+ item_id, user_email=user, workspace_id=scope
42
+ )
43
+ except (KeyError, FileNotFoundError) as exc:
44
+ raise HTTPException(status_code=404, detail=str(exc))
45
+ except ValueError as exc:
46
+ raise HTTPException(status_code=400, detail=str(exc))
47
+
48
+ @router.post("/api/proposals/{item_id}/reject")
49
+ async def reject_proposal(item_id: str, request: Request):
50
+ user = require_user(request)
51
+ scope = gate_write(request)
52
+ try:
53
+ return service.reject(item_id, user_email=user, workspace_id=scope)
54
+ except (KeyError, FileNotFoundError) as exc:
55
+ raise HTTPException(status_code=404, detail=str(exc))
56
+
57
+ return router
58
+
59
+
60
+ __all__ = ["create_change_proposals_router"]
@@ -229,6 +229,7 @@ class AgentHTTPController:
229
229
  "planning_model": req.planning_model or self.model_router.current_model_id,
230
230
  "executing_model": req.executing_model or self.model_router.current_model_id,
231
231
  "reviewing_model": req.reviewing_model or self.model_router.current_model_id,
232
+ "loop": ctx.trace.summary(),
232
233
  }
233
234
 
234
235
  self.runtime.approve(ctx, current_user, approved_by_human=False)
@@ -306,6 +307,7 @@ class AgentHTTPController:
306
307
  "state_history": ctx.state_history,
307
308
  "final_state": ctx.state.value,
308
309
  "created_files": collect_created_files(ctx.transcript),
310
+ "loop": ctx.trace.summary(),
309
311
  }
310
312
 
311
313
  async def resume(
@@ -169,6 +169,9 @@ def _build(config: "Optional[Config]" = None) -> Dict[str, Any]:
169
169
  from latticeai.api.brain_intelligence import create_brain_intelligence_router
170
170
  from latticeai.api.command_center import create_command_center_router
171
171
  from latticeai.services.command_center import CommandCenterService
172
+ from latticeai.api.change_proposals import create_change_proposals_router
173
+ from latticeai.services.change_proposals import ChangeProposalService
174
+ from latticeai.tools import resolve_workspace_path
172
175
  from latticeai.api.memory import create_memory_router
173
176
  from latticeai.api.browser import create_browser_router
174
177
  from latticeai.api.portability import create_portability_router
@@ -1051,6 +1054,23 @@ def _build(config: "Optional[Config]" = None) -> Dict[str, Any]:
1051
1054
  gate_read=PLATFORM.gate_read,
1052
1055
  )
1053
1056
  )
1057
+ CHANGE_PROPOSALS = ChangeProposalService(
1058
+ review_queue=REVIEW_QUEUE,
1059
+ resolve_path=resolve_workspace_path,
1060
+ audit=append_audit_event,
1061
+ )
1062
+ # Proposal-first mutations: the agent loop consults the governor so
1063
+ # additive creates run with minimal friction while changes/deletions of
1064
+ # existing files are staged for review instead of applied.
1065
+ CHAT_AGENT_RUNTIME.deps.change_governor = CHANGE_PROPOSALS
1066
+ app.include_router(
1067
+ create_change_proposals_router(
1068
+ service=CHANGE_PROPOSALS,
1069
+ require_user=require_user,
1070
+ gate_read=PLATFORM.gate_read,
1071
+ gate_write=PLATFORM.gate_write,
1072
+ )
1073
+ )
1054
1074
 
1055
1075
 
1056
1076
  # ── Health & Info ──────────────────────────────────────────────────────────────
@@ -157,7 +157,9 @@ def _start_tunnel(port: int) -> str | None:
157
157
  log_path = Path.home() / ".latticeai" / "tunnel.log"
158
158
  log_path.parent.mkdir(parents=True, exist_ok=True)
159
159
 
160
- proc = subprocess.Popen(
160
+ # Detached on purpose: the tunnel outlives this helper; the log file is
161
+ # the observable surface.
162
+ subprocess.Popen(
161
163
  [bin_path, "tunnel", "--url", f"http://localhost:{port}"],
162
164
  stdout=open(log_path, "w"),
163
165
  stderr=subprocess.STDOUT,