ltcai 1.0.1 → 1.2.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 CHANGED
@@ -36,6 +36,40 @@ Automatic knowledge graph
36
36
  Graph-aware chat, snapshots, memory, agents, workflows, skills, and timeline
37
37
  ```
38
38
 
39
+ ### New in 1.2.0: Server App Modularization
40
+
41
+ - **server_app.py modularized** — Workspace/Organization and health/engine
42
+ endpoints extracted into dedicated routers (`latticeai/api/*`) backed by a
43
+ service layer (`latticeai/services/*`); `server_app` is now app assembly +
44
+ router include (~6,585 → ~5,948 lines)
45
+ - **Routers / services split** — `create_workspace_router`,
46
+ `create_health_router`, `WorkspaceService`, `ModelService`, `ChatService`
47
+ - **Workspace API service layer** — scope resolution and role/permission checks
48
+ centralized in `WorkspaceService`
49
+ - **Workspace / org guardrails** — non-members can't read/write org data,
50
+ viewers can't write, owners/admins manage members; no-auth local owner
51
+ fallback preserved
52
+ - **Health / model / chat modularization** — `/health`, `/mode`,
53
+ `/runtime_features`, `/engines` via the health router; chat trace recording
54
+ via the chat service (streaming behavior unchanged)
55
+ - **Compatibility preserved** — `server:app` import path, all API routes, CLI,
56
+ Knowledge Graph / Admin / Security routers, and VS Code integration unchanged
57
+
58
+ ### New in 1.1.0: Organization Workspace Foundation
59
+
60
+ - **Organization Workspace** alongside Personal Workspace — create shared org
61
+ workspaces, list/switch between them, and archive (non-destructively)
62
+ - **Workspace roles & permissions** — `owner`, `admin`, `member`, `viewer`
63
+ mapped to read / write / manage-members / manage-workspace
64
+ - **Workspace-scoped data** — snapshots, memory, agent runs, workflows, traces,
65
+ and timeline carry a `workspace_id`; reads scope via the `X-Workspace-Id` header
66
+ - **CI / release hardening** — Node.js 24 ready workflow, version-scoped
67
+ artifact upload (never `dist/*`), and a release artifact validator
68
+ - **Enterprise extension foundation (open-core)** — a stable seam for a future
69
+ Enterprise plugin; Community ships everything it has today, unrestricted
70
+ (see [docs/ENTERPRISE.md](docs/ENTERPRISE.md) and
71
+ [docs/EDITION_STRATEGY.md](docs/EDITION_STRATEGY.md))
72
+
39
73
  ### New in 1.0.0: AI Workspace OS
40
74
 
41
75
  - Workspace OS command center at `/workspace`
package/docs/CHANGELOG.md CHANGED
@@ -1,5 +1,104 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.2.0] - 2026-05-31
4
+
5
+ > Server app modularization (routers + service layer) and workspace/org guardrail hardening.
6
+
7
+ ### Changed
8
+
9
+ - **server_app.py modularization (phase 2)** — reduced
10
+ `latticeai/server_app.py` from ~6,585 to ~5,948 lines by extracting the
11
+ Workspace OS / Organization API and the health/engine-summary endpoints into
12
+ dedicated routers backed by a new service layer. `server_app` now focuses on
13
+ app assembly, lifespan, middleware, and router include. The historical
14
+ `server:app` import path, all API paths, and request/response shapes are
15
+ unchanged.
16
+ - **Workspace/Organization guardrails strengthened** — workspace-scoped reads
17
+ and writes now go through `WorkspaceService`, which gates explicitly-named
18
+ workspaces: non-members cannot read or write organization data, viewers
19
+ cannot write, members can write, and only owners/admins manage members. The
20
+ no-auth local-owner fallback for ownerless org workspaces is preserved, but a
21
+ *named* stranger never bypasses membership. `set_active_workspace` continues
22
+ to enforce membership.
23
+
24
+ ### Added
25
+
26
+ - **New API routers** — `latticeai/api/workspace.py`
27
+ (`create_workspace_router`) and `latticeai/api/health.py`
28
+ (`create_health_router`), mirroring the existing auth/admin router-factory
29
+ convention (no import cycle: routers receive dependencies, never import the
30
+ app).
31
+ - **New service layer** — `latticeai/services/workspace_service.py`
32
+ (`WorkspaceService`: scope resolution + permission guardrails),
33
+ `latticeai/services/model_service.py` (`ModelService`: health/engine summary
34
+ payloads), and `latticeai/services/chat_service.py` (`ChatService`: history +
35
+ answer-trace seam; the streaming chat path is unchanged and now records traces
36
+ through this façade).
37
+ - **Shared-global areas made explicit** — the local knowledge graph and
38
+ installed skills remain machine-global shared state (not partitioned per
39
+ workspace); this is now surfaced in `WorkspaceService.SHARED_GLOBAL_AREAS`,
40
+ the `/workspace/os` summary (`shared_global_areas`), and code comments.
41
+ - **Startup/modularization tests** — `tests/unit/test_server_app_modularization.py`
42
+ (import path, router registration, key route presence, no import cycle) and
43
+ `tests/unit/test_workspace_service.py` (read/write/member guardrails).
44
+
45
+ ### Notes
46
+
47
+ - Release metadata aligned to `1.2.0`; `APP_VERSION` continues to derive from
48
+ `WORKSPACE_OS_VERSION` and `/health` reports `1.2.0`.
49
+ - CI release hardening from 1.0.1/1.1.0 is retained (VSIX compile guard, Node.js
50
+ 24, version-scoped artifact validation — no `dist/*` glob).
51
+
52
+ ## [1.1.0] - 2026-05-31
53
+
54
+ > Organization Workspace foundation, open-core Enterprise seam, and CI/release hardening.
55
+
56
+ ### Added
57
+
58
+ - **Organization Workspace foundation** — Workspace OS now distinguishes
59
+ `personal` and `organization` workspace types. A full workspace model
60
+ (`workspace_id`, `name`, `type`, `owner_user_id`, `members`, `roles`,
61
+ `settings`, `created_at`, `updated_at`, `status`) is stored in the existing
62
+ local-first JSON store.
63
+ - **Organization Workspace API** — create org workspace, list workspaces, get
64
+ workspace, update, archive (soft, non-destructive), add/remove member, update
65
+ member role, get workspace summary, activate workspace, and an edition info
66
+ endpoint, exposed under `/workspace/orgs/*`, `/workspace/registry`,
67
+ `/workspace/activate`, and `/workspace/editions`.
68
+ - **Workspace roles and permissions** — `owner`, `admin`, `member`, `viewer`
69
+ mapped to `read` / `write` / `manage_members` / `manage_workspace`. Owners and
70
+ admins manage settings and members; members use the workspace; viewers are
71
+ read-only. Personal workspaces always grant their local user owner rights.
72
+ - **Workspace-scoped data** — Snapshots, Memories, Agent runs, Workflows, answer
73
+ Traces, and Timeline events now carry a `workspace_id`. Reads accept an
74
+ optional `X-Workspace-Id` header / `workspace_id` query to scope results.
75
+ - **Enterprise extension seam (open-core)** — new `latticeai/core/enterprise.py`
76
+ defines an `Edition` enum (`community`/`enterprise`), an
77
+ `EnterpriseCapability` enum, and a runtime `CapabilityRegistry` that a future,
78
+ separately-distributed Enterprise plugin can attach a provider to. The
79
+ Community build ships **zero** enabled Enterprise capabilities and restricts no
80
+ Community feature. Documented in `docs/ENTERPRISE.md` and
81
+ `docs/EDITION_STRATEGY.md`.
82
+ - **Release artifact validator** — `scripts/validate_release_artifacts.py`
83
+ verifies that exactly the expected `whl`/`tar.gz`/`vsix`/`tgz` exist for a
84
+ single version, that internal versions match, that the VSIX contains
85
+ `extension/out/extension.js`, and warns when `dist/` mixes other versions.
86
+ - **Workspace OS UI** — Personal/Organization workspace switcher, current
87
+ workspace indicator, and a minimal organization create / member / role panel
88
+ wired into the existing Workspace OS command center.
89
+
90
+ ### Changed
91
+
92
+ - **CI / release hardening** — `release.yml` opts into Node.js 24
93
+ (`FORCE_JAVASCRIPT_ACTIONS_TO_NODE24`) and bumps `actions/checkout@v5`,
94
+ `actions/setup-node@v5`, `actions/setup-python@v6`. Artifact upload and
95
+ `twine check` are now scoped to the tagged version only — never a `dist/*`
96
+ glob — and the build runs the release artifact validator before upload.
97
+ - Existing 1.0.x Workspace OS state is migrated non-destructively to the v1.1
98
+ workspace model on load; legacy records map to the Personal workspace.
99
+ - Release metadata aligned to `1.1.0` across Python, npm, VS Code extension,
100
+ FastAPI app metadata, and `/health`.
101
+
3
102
  ## [1.0.1] - 2026-05-31
4
103
 
5
104
  > CI packaging fix for the VS Code extension build.
@@ -0,0 +1,56 @@
1
+ # Lattice AI — Edition Strategy (Open Core)
2
+
3
+ This document records the principles behind the Community / Enterprise split so
4
+ the boundary stays predictable for contributors and users.
5
+
6
+ ## Editions
7
+
8
+ - **Community** — this repository, MIT licensed. Local-first AI Workspace OS:
9
+ local LLMs, knowledge graph, Personal **and** Organization workspaces,
10
+ role-based membership, snapshots, memory, agents, workflows, skills, and the
11
+ auditable timeline. Community is a complete product.
12
+ - **Enterprise** — a separately-distributed plugin adding organization-scale
13
+ governance, identity, compliance, and deployment capabilities. Distributed and
14
+ licensed separately. See [ENTERPRISE.md](ENTERPRISE.md).
15
+
16
+ ## Principles
17
+
18
+ 1. **Community is never crippled.** No existing Community feature is removed,
19
+ throttled, or gated to push Enterprise. The capability seam only answers "is
20
+ this *Enterprise* capability available?" — `False` in the open build — and
21
+ never disables a Community code path.
22
+ 2. **Open-core boundary is a runtime seam, not a fork.** Enterprise attaches via
23
+ `capability_registry.register_provider(...)`
24
+ (`latticeai/core/enterprise.py`). The Community repository contains no
25
+ Enterprise implementation and imports no Enterprise code.
26
+ 3. **Capabilities are declared, not hidden.** `EnterpriseCapability` enumerates
27
+ reserved capabilities so the contract is visible and stable, even though
28
+ Community implements none of them.
29
+ 4. **Local-first stays the default.** Enterprise adds options (tenant isolation,
30
+ air-gapped deployment, SIEM export); it does not move the default experience
31
+ off the user's machine.
32
+ 5. **Graceful by default.** A misbehaving or absent provider must never break a
33
+ Community request; the registry falls back to the Community provider.
34
+
35
+ ## What lives where
36
+
37
+ | Concern | Community (this repo) | Enterprise (separate) |
38
+ |--------|------------------------|------------------------|
39
+ | Personal & Organization workspaces | ✅ | — |
40
+ | Base roles (owner/admin/member/viewer) | ✅ | — |
41
+ | Snapshots / memory / agents / workflows / skills | ✅ | — |
42
+ | Audit timeline (local) | ✅ | — |
43
+ | Capability seam & enum | ✅ (declares) | ✅ (implements) |
44
+ | SSO/SCIM/IdP provisioning | seam only | ✅ |
45
+ | Tenant isolation, compliance retention, eDiscovery | seam only | ✅ |
46
+ | SIEM export, DLP, admin policy packs | seam only | ✅ |
47
+ | Private VPC / air-gapped deployment | seam only | ✅ |
48
+
49
+ ## Detecting edition at runtime
50
+
51
+ - `GET /workspace/editions` → edition + per-capability matrix.
52
+ - `GET /workspace/os` → `edition` block in the Workspace OS summary.
53
+ - `latticeai.core.enterprise.detect_edition()` for in-process checks.
54
+
55
+ In the Community build all of the above report `community` with every Enterprise
56
+ capability `false`.
@@ -0,0 +1,78 @@
1
+ # Lattice AI — Enterprise Edition
2
+
3
+ > **Status:** Foundation / extension seam only. The open-source Community
4
+ > edition in this repository ships **none** of the capabilities below enabled,
5
+ > and contains **no** Enterprise implementation. This document describes the
6
+ > boundary and the roadmap, not shipped code.
7
+
8
+ Lattice AI follows an **open-core** model:
9
+
10
+ - **Community** (this repository, MIT) is fully functional on its own: local
11
+ LLMs, knowledge graph, Personal and Organization workspaces, roles, snapshots,
12
+ memory, agents, workflows, skills, and the auditable timeline.
13
+ - **Enterprise** is a separately-distributed plugin that attaches advanced,
14
+ organization-scale governance and deployment capabilities through a stable
15
+ runtime seam. It is never bundled into the Community build.
16
+
17
+ See [EDITION_STRATEGY.md](EDITION_STRATEGY.md) for the principles that keep this
18
+ boundary honest (Community is never crippled to upsell Enterprise).
19
+
20
+ ## The extension seam
21
+
22
+ The seam lives in [`latticeai/core/enterprise.py`](../latticeai/core/enterprise.py):
23
+
24
+ - `Edition` — `community` (default) or `enterprise`.
25
+ - `EnterpriseCapability` — the enum of reserved capabilities (below).
26
+ - `CapabilityProvider` — the protocol an Enterprise plugin implements.
27
+ - `capability_registry` — a process-wide registry. An Enterprise plugin calls
28
+ `capability_registry.register_provider(...)` at startup. Until then, the
29
+ default `CommunityCapabilityProvider` answers every capability query with
30
+ "Community / disabled".
31
+
32
+ Community code consults the seam at extension points via
33
+ `is_capability_enabled(EnterpriseCapability.X)`. In the Community build this is
34
+ always `False`, so the Community code path is taken and nothing is gated off.
35
+
36
+ The live edition + capability matrix is exposed at `GET /workspace/editions`
37
+ and surfaced in the Workspace OS summary (`GET /workspace/os` → `edition`).
38
+
39
+ ## Enterprise capability roadmap
40
+
41
+ These are declared in `EnterpriseCapability` so the seam is stable and
42
+ discoverable. None are implemented in Community.
43
+
44
+ | Capability | Enum | Summary |
45
+ |-----------|------|---------|
46
+ | Advanced SSO | `SSO_ADVANCED` | Enforced SSO, session policy, SAML/OIDC federation |
47
+ | IdP provisioning | `IDP_PROVISIONING` | Entra ID / Okta user & group provisioning |
48
+ | SCIM | `SCIM` | SCIM 2.0 user/group lifecycle sync |
49
+ | Advanced RBAC/ABAC | `RBAC_ABAC_ADVANCED` | Custom roles, attribute-based policy beyond the 4 base roles |
50
+ | Tenant isolation | `TENANT_ISOLATION` | Hard multi-tenant data isolation |
51
+ | Compliance retention | `COMPLIANCE_RETENTION` | Legal-hold, retention windows, immutable audit |
52
+ | SIEM export | `SIEM_EXPORT` | Streaming audit/event export to Splunk/Sentinel/etc. |
53
+ | Private VPC | `PRIVATE_VPC` | Private-network / customer-VPC deployment controls |
54
+ | Air-gapped deployment | `AIR_GAPPED_DEPLOYMENT` | Fully offline install & update channel |
55
+ | DLP policy | `DLP_POLICY` | Data-loss-prevention scanning & enforcement |
56
+ | eDiscovery | `EDISCOVERY` | Search, hold, and export for legal discovery |
57
+ | Admin policy packs | `ADMIN_POLICY_PACKS` | Centrally-managed org policy bundles |
58
+
59
+ ## How an Enterprise plugin attaches (illustrative)
60
+
61
+ ```python
62
+ from latticeai.core.enterprise import (
63
+ Edition, EnterpriseCapability, capability_registry,
64
+ )
65
+
66
+ class EnterpriseProvider:
67
+ def edition(self) -> Edition:
68
+ return Edition.ENTERPRISE
69
+
70
+ def is_enabled(self, capability: EnterpriseCapability) -> bool:
71
+ return capability in MY_LICENSED_CAPABILITIES
72
+
73
+ # Enterprise package startup:
74
+ capability_registry.register_provider(EnterpriseProvider())
75
+ ```
76
+
77
+ No Enterprise code or credentials live in this repository; the Community build
78
+ imports none of the above.
@@ -1,3 +1,3 @@
1
1
  """Lattice AI - modular server package."""
2
2
 
3
- __version__ = "1.0.1"
3
+ __version__ = "1.2.0"
@@ -0,0 +1,45 @@
1
+ """Health / status / engine-summary router.
2
+
3
+ Extracted from ``server_app.py`` in v1.2.0. Paths unchanged: ``/health``,
4
+ ``/mode``, ``/runtime_features``, ``/engines`` (GET). Heavier engine *mutation*
5
+ endpoints (install / verify-cloud / pull-model) stay in server_app for now.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import asyncio
11
+ from typing import Any, Callable, List, Optional
12
+
13
+ from fastapi import APIRouter, Request
14
+
15
+
16
+ def create_health_router(
17
+ *,
18
+ model_service,
19
+ engine_status: Callable[[], List[dict]],
20
+ get_current_user: Callable[[Request], Optional[str]],
21
+ require_auth: bool,
22
+ app_version: str,
23
+ app_mode: str,
24
+ ) -> APIRouter:
25
+ router = APIRouter()
26
+ svc = model_service
27
+
28
+ @router.get("/health")
29
+ async def health(request: Request):
30
+ base = svc.health_base(version=app_version, mode=app_mode)
31
+ if not get_current_user(request) and require_auth:
32
+ return base
33
+ engines = await asyncio.to_thread(engine_status)
34
+ return svc.health_full(base, engines)
35
+
36
+ @router.get("/mode")
37
+ @router.get("/runtime_features")
38
+ async def mode():
39
+ return svc.runtime()
40
+
41
+ @router.get("/engines")
42
+ async def engines():
43
+ return svc.engines_payload(await asyncio.to_thread(engine_status))
44
+
45
+ return router