ltcai 11.7.0 → 11.9.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 (136) hide show
  1. package/README.md +73 -70
  2. package/docs/BENCHMARKS.md +9 -2
  3. package/docs/CHANGELOG.md +157 -0
  4. package/docs/CI_AND_RELEASE_GATES.md +126 -41
  5. package/docs/COMMUNITY_AND_PLUGINS.md +1 -1
  6. package/docs/DEVELOPMENT.md +34 -14
  7. package/docs/LEGACY_COMPATIBILITY.md +10 -6
  8. package/docs/ONBOARDING.md +5 -3
  9. package/docs/OPERATIONS.md +5 -1
  10. package/docs/PERMISSION_MODE.md +14 -9
  11. package/docs/TRUST_MODEL.md +13 -6
  12. package/docs/USABILITY_AUDIT.md +5 -0
  13. package/docs/WHY_LATTICE.md +6 -4
  14. package/docs/kg-schema.md +7 -3
  15. package/docs/mcp-tools.md +73 -79
  16. package/docs/security-model.md +6 -3
  17. package/lattice_brain/__init__.py +1 -1
  18. package/lattice_brain/graph/_kg_common/__init__.py +1 -54
  19. package/lattice_brain/graph/_kg_common/text.py +14 -450
  20. package/lattice_brain/ingestion/__init__.py +6 -3
  21. package/lattice_brain/multimodal/__init__.py +9 -3
  22. package/latticeai/__init__.py +1 -1
  23. package/latticeai/api/agent_worker_seam.py +12 -1
  24. package/latticeai/api/models.py +18 -110
  25. package/latticeai/api/search.py +7 -30
  26. package/latticeai/api/worker_compute.py +53 -107
  27. package/latticeai/api/worker_seams.py +17 -2
  28. package/latticeai/core/http_origin.py +3 -3
  29. package/latticeai/core/messages.py +0 -5
  30. package/latticeai/core/policy.py +1 -6
  31. package/latticeai/core/quiet.py +1 -20
  32. package/latticeai/core/security.py +29 -83
  33. package/latticeai/core/sessions.py +95 -4
  34. package/latticeai/core/users.py +0 -38
  35. package/latticeai/models/router/catalog.py +2 -2
  36. package/latticeai/models/router/generation.py +81 -14
  37. package/latticeai/models/router/loading.py +41 -5
  38. package/latticeai/runtime/access_runtime.py +7 -4
  39. package/latticeai/runtime/build_phases/features.py +8 -31
  40. package/latticeai/runtime/build_phases/foundation.py +7 -16
  41. package/latticeai/runtime/build_phases/web.py +3 -3
  42. package/latticeai/runtime/build_phases/worker_profile.py +21 -28
  43. package/latticeai/runtime/runtime_context.py +0 -2
  44. package/latticeai/services/architecture_readiness.py +18 -19
  45. package/latticeai/services/process_audit.py +1 -22
  46. package/latticeai/services/product_readiness.py +33 -11
  47. package/latticeai/services/voice_capture.py +8 -28
  48. package/latticeai/tools/__init__.py +6 -46
  49. package/latticeai/tools/commands.py +9 -15
  50. package/latticeai/tools/knowledge.py +0 -6
  51. package/package.json +3 -5
  52. package/requirements.txt +0 -1
  53. package/scripts/check_current_release_docs.mjs +1 -1
  54. package/scripts/check_openapi_drift.mjs +3 -2
  55. package/scripts/check_server_i18n.mjs +5 -4
  56. package/scripts/compose_openapi.py +2 -1
  57. package/scripts/export_openapi.py +5 -4
  58. package/scripts/gen_worker_allowlist_fixture.py +2 -2
  59. package/scripts/openapi_route_families.json +14 -73
  60. package/scripts/release_screen_claims.json +131 -27
  61. package/src-tauri/Cargo.lock +11 -10
  62. package/src-tauri/Cargo.toml +1 -1
  63. package/src-tauri/tauri.conf.json +1 -1
  64. package/static/app/asset-manifest.json +41 -41
  65. package/static/app/assets/{Act-BPcVAbOL.js → Act-B4WT81kh.js} +1 -1
  66. package/static/app/assets/AdminConsole--Wf71m-o.js +1 -0
  67. package/static/app/assets/{Brain-CT92Kos0.js → Brain-CtYaa26c.js} +2 -2
  68. package/static/app/assets/BrainHome-Be2VPJEc.js +2 -0
  69. package/static/app/assets/BrainSignals-C0__xgpG.js +1 -0
  70. package/static/app/assets/Capture-DdNi5Peb.js +1 -0
  71. package/static/app/assets/Chronicle-B3hNveeI.js +1 -0
  72. package/static/app/assets/CommandPalette-CIsnSsFL.js +1 -0
  73. package/static/app/assets/Library-Bl5XClFV.js +1 -0
  74. package/static/app/assets/LivingBrain-DjkTB_gh.js +1 -0
  75. package/static/app/assets/{ProductFlow-DXBC6brE.js → ProductFlow-DCUNRNHs.js} +1 -1
  76. package/static/app/assets/{ReviewCard-HXRle3qq.js → ReviewCard-CD3yWvUB.js} +2 -2
  77. package/static/app/assets/System-BJ6jQ_SL.js +1 -0
  78. package/static/app/assets/arrow-left-6_28Z0qH.js +1 -0
  79. package/static/app/assets/{bot-Cn8bWRuq.js → bot-Bc3Q27YR.js} +1 -1
  80. package/static/app/assets/brain-B9BDrMTe.js +1 -0
  81. package/static/app/assets/{button-Ct9f2_oT.js → button-D6JcpYcf.js} +1 -1
  82. package/static/app/assets/circle-check-BFu9lD-3.js +1 -0
  83. package/static/app/assets/{circle-pause-CmzC_apg.js → circle-pause-BGMiV8UU.js} +1 -1
  84. package/static/app/assets/{circle-play-D8mW2aQ7.js → circle-play-DoanLHnd.js} +1 -1
  85. package/static/app/assets/{cpu-DZcdd0PZ.js → cpu-DwzNf82m.js} +1 -1
  86. package/static/app/assets/{download-bv1KEPGQ.js → download-Ddw49yCV.js} +1 -1
  87. package/static/app/assets/{folder-open-d-Pip5gr.js → folder-open-Brd6Kvto.js} +1 -1
  88. package/static/app/assets/{hard-drive-D20iavUb.js → hard-drive-Bu-DTJdB.js} +1 -1
  89. package/static/app/assets/index-CGdg_aq9.css +2 -0
  90. package/static/app/assets/{index-Do83hDzJ.js → index-CWKRRsLW.js} +4 -4
  91. package/static/app/assets/input-CEqsxtil.js +1 -0
  92. package/static/app/assets/{link-2-BPJOFlAy.js → link-2-DZ4OA5tJ.js} +1 -1
  93. package/static/app/assets/{permissionCopy-ChdJd493.js → permissionCopy-D9TR0F8b.js} +1 -1
  94. package/static/app/assets/primitives-DORg7Z_7.js +1 -0
  95. package/static/app/assets/search-0NQ21wXe.js +1 -0
  96. package/static/app/assets/{share-2-YNX_NtMU.js → share-2-BC5FirFv.js} +1 -1
  97. package/static/app/assets/{shield-alert-DuQ3zrVL.js → shield-alert-DUbR2W2s.js} +1 -1
  98. package/static/app/assets/textarea-jtQcRSXo.js +1 -0
  99. package/static/app/assets/{useFocusTrap-ZVI98jaW.js → useFocusTrap-HRemcWId.js} +1 -1
  100. package/static/app/assets/{useMutation-CVC4qv_D.js → useMutation-DqlFE-Bw.js} +1 -1
  101. package/static/app/assets/{useQuery-C7BeG4HU.js → useQuery-BizqBNGw.js} +1 -1
  102. package/static/app/assets/utils-WgW4V69R.js +4 -0
  103. package/static/app/assets/workspace-DSek3jCY.js +1 -0
  104. package/static/app/index.html +4 -4
  105. package/static/sw.js +1 -1
  106. package/lattice_brain/ingestion/pipeline.py +0 -108
  107. package/latticeai/api/local_files.py +0 -44
  108. package/latticeai/api/tools.py +0 -126
  109. package/latticeai/api/voice_capture.py +0 -32
  110. package/latticeai/core/agent_permission.py +0 -85
  111. package/scripts/agent_eval.py +0 -34
  112. package/scripts/brain_quality_eval.py +0 -37
  113. package/scripts/check_legacy_debt.mjs +0 -91
  114. package/scripts/check_python.py +0 -100
  115. package/scripts/chunking_parity_corpus.py +0 -449
  116. package/scripts/generate_agent_parity_fixtures.py +0 -771
  117. package/scripts/generate_chunking_parity_fixtures.py +0 -259
  118. package/static/app/assets/AdminConsole-Bw1ATQL0.js +0 -1
  119. package/static/app/assets/BrainHome-CFBkt1K_.js +0 -2
  120. package/static/app/assets/BrainSignals-ReLWF2H8.js +0 -1
  121. package/static/app/assets/Capture-BsTokYkk.js +0 -1
  122. package/static/app/assets/Chronicle-B6f0T9id.js +0 -1
  123. package/static/app/assets/CommandPalette-CuvjTv1u.js +0 -1
  124. package/static/app/assets/Library-BGJbG9Hd.js +0 -1
  125. package/static/app/assets/LivingBrain-DGYK_Jsa.js +0 -1
  126. package/static/app/assets/System-CMHSO9qM.js +0 -1
  127. package/static/app/assets/arrow-left-BfmkskWx.js +0 -1
  128. package/static/app/assets/brain-CQJberbE.js +0 -1
  129. package/static/app/assets/circle-check-DruOxB-4.js +0 -1
  130. package/static/app/assets/index-D9x-kSNy.css +0 -2
  131. package/static/app/assets/input-BLXVNmj1.js +0 -1
  132. package/static/app/assets/primitives-Cv5tbZBY.js +0 -1
  133. package/static/app/assets/search-CT9aho2j.js +0 -1
  134. package/static/app/assets/textarea-DqwLnli4.js +0 -1
  135. package/static/app/assets/utils-CiFtIdZq.js +0 -4
  136. package/static/app/assets/workspace-DQz9vIId.js +0 -1
@@ -1,85 +0,0 @@
1
- """Agent-loop permission-mode gates (v9.9.8) — the two the parity fixtures pin.
2
-
3
- These were the Python loop's mode tables, called by ``SingleAgentRuntime`` and
4
- ``build_agent_runtime``. Orchestration moved to ``lattice-agent`` in v11.6.0 and
5
- the Python loop is gone, so **nothing in the worker imports this module**.
6
-
7
- It survives for one reason, stated so it is not read as a leftover:
8
- ``scripts/generate_agent_parity_fixtures.py`` produces the committed goldens
9
- ``rust/fixtures`` holds for the Rust loop's permission gates, and it derives
10
- them from :func:`block_reason_for_tool` and :func:`non_auto_plan_steps` here.
11
- Deleting these two would leave the Rust side asserting against fixtures no
12
- Python could regenerate — the fixtures would still pass, and would stop meaning
13
- anything. The rest of the module (``call_mode_source``, ``resolve_deps_mode``,
14
- ``approval_requirements_for``) went with the loop that called it.
15
- """
16
-
17
- from __future__ import annotations
18
-
19
- from typing import Any, List, Mapping, Optional, Sequence
20
-
21
- from latticeai.core.permission_mode import (
22
- PermissionMode,
23
- effective_auto_approve,
24
- is_circuit_breaker,
25
- normalize_mode,
26
- )
27
-
28
-
29
- def non_auto_plan_steps(
30
- mode: PermissionMode | str,
31
- steps: Sequence[Mapping[str, Any]],
32
- tool_governance: Mapping[str, Mapping[str, Any]],
33
- *,
34
- governed_tools: Optional[Any] = None,
35
- ) -> List[Any]:
36
- """Plan steps that still need approval under the active mode."""
37
- mode = normalize_mode(mode)
38
- governed = frozenset(governed_tools or ())
39
- non_auto: List[Any] = []
40
- for step in steps:
41
- name = step.get("action")
42
- if not name:
43
- continue
44
- if name in governed and mode == PermissionMode.STRICT:
45
- # Strict keeps governor tools out of the plan-level block (per-call).
46
- continue
47
- policy = dict(tool_governance.get(name) or {
48
- "auto_approve": False, "risk": "write", "destructive": False,
49
- "shell": False, "network": False, "sandbox": "workspace", "rollback": "none",
50
- })
51
- if effective_auto_approve(mode, str(name), policy):
52
- continue
53
- non_auto.append(name)
54
- return non_auto
55
-
56
-
57
- def block_reason_for_tool(
58
- mode: PermissionMode | str,
59
- name: str,
60
- policy: Mapping[str, Any],
61
- args: Mapping[str, Any],
62
- *,
63
- approved_by_human: bool = False,
64
- governor_allows_additive: bool = False,
65
- ) -> Optional[str]:
66
- """Return a block reason, or None when the call may proceed."""
67
- mode = normalize_mode(mode)
68
- breaker = is_circuit_breaker(name, policy, args)
69
- if breaker:
70
- return f"BLOCKED: {breaker}"
71
- if policy.get("risk") == "destructive" or policy.get("destructive"):
72
- return f"BLOCKED: destructive action '{name}' not permitted in agent mode."
73
- if approved_by_human or governor_allows_additive:
74
- return None
75
- if effective_auto_approve(mode, name, policy, args=args):
76
- return None
77
- if policy.get("auto_approve"):
78
- return None
79
- return f"BLOCKED: action '{name}' requires explicit approval (mode={mode.value})."
80
-
81
-
82
- __all__ = [
83
- "block_reason_for_tool",
84
- "non_auto_plan_steps",
85
- ]
@@ -1,34 +0,0 @@
1
- #!/usr/bin/env python3
2
- """Agent-loop evaluation gate — native since v11.6.0.
3
-
4
- The deterministic scenario suite used to live in
5
- ``latticeai.core.agent_eval`` and drive ``SingleAgentRuntime``. That loop is
6
- ``lattice-agent`` now. CI still invokes this path; we verify the native suite
7
- is present rather than importing the deleted Python runtime.
8
-
9
- Last Python generating tree: commit fc65e60.
10
- Goldens: ``rust/fixtures/agent_loop/golden/`` (FROZEN).
11
- """
12
-
13
- from __future__ import annotations
14
-
15
- from pathlib import Path
16
-
17
- REPO = Path(__file__).resolve().parents[1]
18
- REQUIRED = (
19
- REPO / "rust" / "lattice-agent" / "tests" / "agent_loop.rs",
20
- REPO / "rust" / "fixtures" / "agent_loop" / "golden",
21
- )
22
-
23
-
24
- def main() -> int:
25
- missing = [str(path.relative_to(REPO)) for path in REQUIRED if not path.exists()]
26
- if missing:
27
- print("agent-loop-eval: FAIL missing native artifacts:", missing)
28
- return 1
29
- print("agent-loop-eval: native lattice-agent suite present (Python loop retired)")
30
- return 0
31
-
32
-
33
- if __name__ == "__main__":
34
- raise SystemExit(main())
@@ -1,37 +0,0 @@
1
- #!/usr/bin/env python3
2
- """Brain recall / KG quality eval — native since v11.6.0.
3
-
4
- This used to import ``KnowledgeGraphStore``, ``RetrievalBenchmarkRunner`` and
5
- ``MemoryService`` and run the Python retrieval bench. Retrieval and the
6
- store are ``lattice-retrieval`` / ``lattice-core`` now. CI still invokes
7
- this path; we verify the native goldens and the worker embedder report
8
- are present.
9
-
10
- Last Python generating tree: commit fc65e60.
11
- Goldens: ``rust/fixtures/golden/`` (FROZEN).
12
- """
13
-
14
- from __future__ import annotations
15
-
16
- from pathlib import Path
17
-
18
- REPO = Path(__file__).resolve().parents[1]
19
- REQUIRED = (
20
- REPO / "rust" / "fixtures" / "golden" / "manifest.json",
21
- REPO / "rust" / "fixtures" / "parity_store.sqlite",
22
- REPO / "latticeai" / "api" / "search.py",
23
- REPO / "latticeai" / "services" / "search_service.py",
24
- )
25
-
26
-
27
- def main() -> int:
28
- missing = [str(path.relative_to(REPO)) for path in REQUIRED if not path.exists()]
29
- if missing:
30
- print("brain-quality-eval: FAIL missing native artifacts:", missing)
31
- return 1
32
- print("brain-quality-eval: native retrieval goldens present (Python store retired)")
33
- return 0
34
-
35
-
36
- if __name__ == "__main__":
37
- raise SystemExit(main())
@@ -1,91 +0,0 @@
1
- #!/usr/bin/env node
2
- // Legacy debt gate (9.9.1): the root shim layer stays removed.
3
- //
4
- // Fails when:
5
- // 1. a Python module other than server.py appears at the repository root;
6
- // 2. any source tree imports a removed root shim module;
7
- // 3. a removed shim directory (tools/) reappears at the root.
8
- //
9
- // Mirror of tests/unit/test_legacy_root_shims.py, but static and runnable in
10
- // `npm run lint` without a Python environment.
11
- import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
12
- import { join, relative } from "node:path";
13
-
14
- const repo = join(import.meta.dirname, "..");
15
-
16
- const ALLOWED_ROOT_MODULES = new Set(["server.py"]);
17
- const REMOVED_ROOT_DIRS = ["tools"];
18
- const REMOVED_MODULES = [
19
- "ltcai_cli",
20
- "auto_setup",
21
- "setup_wizard",
22
- "mcp_registry",
23
- "kg_schema",
24
- "knowledge_graph",
25
- "knowledge_graph_api",
26
- "local_knowledge_api",
27
- "llm_router",
28
- "p_reinforce",
29
- "telegram_bot",
30
- "tools",
31
- ];
32
- // Trees that must not import removed shims. static/app and node_modules are
33
- // build output; src-tauri/target is compiler output.
34
- const SOURCE_TREES = ["latticeai", "lattice_brain", "tests", "scripts", "bin"];
35
-
36
- const failures = [];
37
-
38
- for (const entry of readdirSync(repo)) {
39
- if (entry.endsWith(".py") && !ALLOWED_ROOT_MODULES.has(entry)) {
40
- failures.push(`root module reappeared: ${entry} — put code in latticeai/ or lattice_brain/`);
41
- }
42
- }
43
- for (const dir of REMOVED_ROOT_DIRS) {
44
- if (existsSync(join(repo, dir))) {
45
- failures.push(`removed root package reappeared: ${dir}/ — use latticeai.${dir} instead`);
46
- }
47
- }
48
-
49
- const modulePattern = REMOVED_MODULES.join("|");
50
- const pyImport = new RegExp(`^\\s*(?:import\\s+(?:${modulePattern})\\b|from\\s+(?:${modulePattern})\\s+import\\b)`);
51
- const jsSpawn = new RegExp(`(?:${modulePattern})\\.py\\b`);
52
-
53
- function* walk(dir) {
54
- for (const entry of readdirSync(dir)) {
55
- if (entry === "__pycache__" || entry === "node_modules" || entry === ".venv") continue;
56
- const full = join(dir, entry);
57
- const st = statSync(full);
58
- if (st.isDirectory()) yield* walk(full);
59
- else yield full;
60
- }
61
- }
62
-
63
- for (const tree of SOURCE_TREES) {
64
- const base = join(repo, tree);
65
- if (!existsSync(base)) continue;
66
- for (const file of walk(base)) {
67
- const rel = relative(repo, file);
68
- if (/\.py$/.test(file)) {
69
- const lines = readFileSync(file, "utf8").split("\n");
70
- lines.forEach((line, i) => {
71
- if (pyImport.test(line)) {
72
- failures.push(`${rel}:${i + 1} imports a removed root shim: ${line.trim()}`);
73
- }
74
- });
75
- } else if (/\.(mjs|cjs|js)$/.test(file) && !/\.min\.js$/.test(file)) {
76
- const lines = readFileSync(file, "utf8").split("\n");
77
- lines.forEach((line, i) => {
78
- if (jsSpawn.test(line) && !line.includes("check_legacy_debt")) {
79
- failures.push(`${rel}:${i + 1} references a removed root shim file: ${line.trim()}`);
80
- }
81
- });
82
- }
83
- }
84
- }
85
-
86
- if (failures.length > 0) {
87
- console.error("legacy debt gate FAILED:");
88
- for (const failure of failures) console.error(` - ${failure}`);
89
- process.exit(1);
90
- }
91
- console.log("legacy debt gate ok: root shim layer stays removed (server.py only)");
@@ -1,100 +0,0 @@
1
- #!/usr/bin/env python3
2
- """Discover-and-syntax-check every first-party Python module.
3
-
4
- Replaces the hand-maintained ``py_compile`` enumeration in CI and
5
- ``package.json``: walks the repository, skips vendored / virtualenv / build /
6
- cache / generated directories, and checks everything that remains. New
7
- modules are picked up automatically — there is nothing to update when a file is
8
- added, so the syntax gate can never silently fall behind the codebase.
9
-
10
- Unlike ``py_compile``, this script does not write ``.pyc`` files or create
11
- ``__pycache__`` directories. Validation should not dirty a developer's working
12
- tree or leave generated files for later lint passes to trip over.
13
-
14
- Usage::
15
-
16
- python scripts/check_python.py # syntax-check all discovered modules
17
- python scripts/check_python.py --list # just print what would be checked
18
-
19
- Exit code is non-zero if any module fails to parse.
20
- """
21
-
22
- from __future__ import annotations
23
-
24
- import sys
25
- from pathlib import Path
26
-
27
- ROOT = Path(__file__).resolve().parent.parent
28
-
29
- # Directory names excluded anywhere in the tree: virtualenvs, build/cache
30
- # artifacts, generated agent output, and vendored snapshots of older releases.
31
- EXCLUDE_DIRS = {
32
- ".git",
33
- ".venv",
34
- "venv",
35
- "env",
36
- ".build-venv",
37
- ".npm-cache",
38
- "build",
39
- "dist",
40
- "node_modules",
41
- "__pycache__",
42
- ".pytest_cache",
43
- ".mypy_cache",
44
- ".ruff_cache",
45
- "agent_workspace",
46
- "outputs",
47
- "playwright-report",
48
- "test-results",
49
- "ltcai.egg-info",
50
- "output",
51
- ".ltcai",
52
- ".ltcai-brain",
53
- ".ltcai-test",
54
- # Vendored snapshot of an older packaged release — not part of the build.
55
- "ltcai-0.3.1",
56
- }
57
-
58
-
59
- def iter_modules():
60
- for path in ROOT.rglob("*.py"):
61
- parts = path.relative_to(ROOT).parts
62
- if any(part in EXCLUDE_DIRS for part in parts):
63
- continue
64
- yield path
65
-
66
-
67
- def check_syntax(path: Path) -> str | None:
68
- """Return a human-readable failure string, or ``None`` when syntax is valid."""
69
-
70
- try:
71
- compile(path.read_bytes(), str(path), "exec", dont_inherit=True)
72
- except (OSError, SyntaxError, ValueError) as exc:
73
- return f"{path.relative_to(ROOT)}: {exc}"
74
- return None
75
-
76
-
77
- def main(argv: list[str]) -> int:
78
- modules = sorted(iter_modules())
79
- if "--list" in argv:
80
- for path in modules:
81
- print(path.relative_to(ROOT))
82
- return 0
83
-
84
- failures: list[str] = []
85
- for path in modules:
86
- failure = check_syntax(path)
87
- if failure:
88
- failures.append(failure)
89
-
90
- if failures:
91
- print("\n".join(failures))
92
- print(f"check:python FAILED — {len(failures)} of {len(modules)} module(s) did not parse")
93
- return 1
94
-
95
- print(f"check:python OK — syntax-checked {len(modules)} modules")
96
- return 0
97
-
98
-
99
- if __name__ == "__main__":
100
- raise SystemExit(main(sys.argv[1:]))