diff --git a/README.md b/README.md
index 0b4a5c61..524b13f4 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,12 @@
+
+
+[](https://github.com/lobster-trap/zeroeye/actions)
+[](https://editorconfig.org)
+[](https://github.com/lobster-trap/zeroeye/blob/main/LICENSE)
+[](https://github.com/lobster-trap/zeroeye)
+
+
+
# Tent of Trials
Trading and risk platform.
diff --git a/build.py b/build.py
index cf51696c..24886e76 100644
--- a/build.py
+++ b/build.py
@@ -18,12 +18,49 @@
DIAGNOSTIC_DIR = ROOT / "diagnostic"
DIAGNOSTIC_CHUNK_SIZE = 40 * 1024 * 1024
ENCRYPTLY_BLOCKER_MESSAGE = "encryptly could not create an archive. You may have timed out; try launching it in the background and waiting for it to finish with no timeout due to a bug in encryptly."
+TEXT_ENCODING = "utf-8"
+
+
+def configure_text_encoding() -> None:
+ """Use UTF-8 consistently for our console and captured child-process text."""
+ os.environ.setdefault("PYTHONIOENCODING", TEXT_ENCODING)
+ for stream in (sys.stdout, sys.stderr):
+ reconfigure = getattr(stream, "reconfigure", None)
+ if reconfigure is None:
+ continue
+ try:
+ reconfigure(encoding=TEXT_ENCODING, errors="replace")
+ except Exception:
+ try:
+ reconfigure(errors="replace")
+ except Exception:
+ pass
+
+
+def subprocess_env(env: Optional[dict[str, str]] = None) -> dict[str, str]:
+ merged = os.environ.copy() if env is None else env.copy()
+ merged.setdefault("PYTHONIOENCODING", TEXT_ENCODING)
+ return merged
+
+
+def run_text_process(cmd: list[str], **kwargs) -> subprocess.CompletedProcess[str]:
+ """Run a subprocess with deterministic UTF-8 text decoding."""
+ kwargs.setdefault("text", True)
+ if kwargs.get("text") is not False:
+ kwargs.setdefault("encoding", TEXT_ENCODING)
+ kwargs.setdefault("errors", "replace")
+ if kwargs.get("env") is not None:
+ kwargs["env"] = subprocess_env(kwargs["env"])
+ return subprocess.run(cmd, **kwargs)
+
+
+configure_text_encoding()
def current_commit_id() -> str:
"""Return the first 4 bytes (8 hex chars) of HEAD for stable per-commit diagnostics."""
try:
- result = subprocess.run(
+ result = run_text_process(
["git", "rev-parse", "--verify", "HEAD"],
cwd=str(ROOT),
capture_output=True,
@@ -231,18 +268,20 @@ def check_encryptly_runs(timeout: int = 600) -> tuple[bool, str]:
workspace = Path.home() / ".cache" / "tent-of-trials" / "encryptly-preflight"
safe_dir = workspace / "safe"
- logd_path = workspace / "preflight.logd"
+ output_dir = workspace / "out"
+ logd_path = output_dir / "preflight.logd"
try:
shutil.rmtree(workspace, ignore_errors=True)
safe_dir.mkdir(parents=True, exist_ok=True)
+ output_dir.mkdir(parents=True, exist_ok=True)
(safe_dir / "preflight.txt").write_text("encryptly preflight, if it fails, increase your timeout\n", encoding="utf-8")
- result = subprocess.run(
+ result = run_text_process(
[
str(encryptly_bin),
"pack",
str(logd_path),
"--include",
- str(workspace),
+ str(safe_dir),
"--max-file-size",
"32000",
],
@@ -251,9 +290,9 @@ def check_encryptly_runs(timeout: int = 600) -> tuple[bool, str]:
text=True,
timeout=timeout,
)
- # if result.returncode != 0:
- # output = result.stderr.strip() or result.stdout.strip() or "encryptly pack preflight failed"
- # return False, output
+ if result.returncode != 0:
+ output = result.stderr.strip() or result.stdout.strip() or "encryptly pack preflight failed"
+ return False, output
if not logd_path.exists():
return False, "encryptly preflight completed without creating a .logd"
return True, "encryptly preflight passed"
@@ -320,7 +359,7 @@ def build_module(
if not node_modules.exists():
print(f" {color('npm install...', Colors.GRAY)}")
try:
- install_result = subprocess.run(
+ install_result = run_text_process(
["npm", "install"],
cwd=str(module.dir),
capture_output=not verbose,
@@ -337,7 +376,7 @@ def build_module(
build_type = "Release" if release else "Debug"
try:
- cfg_result = subprocess.run(
+ cfg_result = run_text_process(
["cmake", "-S", ".", "-B", "build",
f"-DCMAKE_BUILD_TYPE={build_type}"],
cwd=str(module.dir),
@@ -371,7 +410,7 @@ def build_module(
cmd.append("--release")
try:
- result = subprocess.run(
+ result = run_text_process(
cmd,
cwd=str(module.dir),
capture_output=True,
@@ -400,7 +439,7 @@ def build_module(
def clean_module(module: Module, verbose: bool = False) -> bool:
print(f" {color('▸', Colors.YELLOW)} Cleaning {module.name}...")
try:
- subprocess.run(
+ run_text_process(
module.clean_cmd,
cwd=str(module.dir),
capture_output=not verbose,
@@ -430,7 +469,7 @@ def verify_binary(module: Module) -> Optional[str]:
def run_cmd(cmd: list[str], **kwargs) -> tuple[bool, str]:
try:
- result = subprocess.run(
+ result = run_text_process(
cmd, capture_output=True, text=True, check=False, **kwargs
)
output = result.stdout
@@ -551,7 +590,7 @@ def commit_diagnostic_artifacts(paths: list[Path], commit_id: str) -> bool:
return False
relpaths = [str(path.relative_to(ROOT)) for path in existing]
- status = subprocess.run(
+ status = run_text_process(
["git", "status", "--porcelain", "--", *relpaths],
cwd=str(ROOT),
capture_output=True,
@@ -565,7 +604,7 @@ def commit_diagnostic_artifacts(paths: list[Path], commit_id: str) -> bool:
print(f" {color('✓', Colors.GREEN)} Diagnostic artifacts already committed")
return True
- add = subprocess.run(
+ add = run_text_process(
["git", "add", "--", *relpaths],
cwd=str(ROOT),
capture_output=True,
@@ -576,7 +615,7 @@ def commit_diagnostic_artifacts(paths: list[Path], commit_id: str) -> bool:
print(f" {color('✗', Colors.RED)} Could not stage diagnostic artifacts: {add.stderr.strip()}")
return False
- commit = subprocess.run(
+ commit = run_text_process(
["git", "commit", "-m", f"Add build diagnostics for {commit_id}", "--", *relpaths],
cwd=str(ROOT),
capture_output=True,
@@ -666,7 +705,7 @@ def generate_logd(
log_lines.append(output)
(safe_dir / "build.log").write_text("\n".join(log_lines), encoding="utf-8")
- sr = subprocess.run(
+ sr = run_text_process(
[
str(encryptly_bin),
"pack",
diff --git a/diagnostic/build-1841e074.json b/diagnostic/build-1841e074.json
new file mode 100644
index 00000000..a7d3760c
--- /dev/null
+++ b/diagnostic/build-1841e074.json
@@ -0,0 +1,87 @@
+{
+ "generated_at": "2026-06-18T09:15:27.735058+00:00",
+ "commit": "1841e074",
+ "diagnostic_logd": "diagnostic/build-1841e074.logd",
+ "diagnostic_logd_error": null,
+ "message_blocker": null,
+ "chunked": false,
+ "chunk_size_bytes": null,
+ "password": "28ff9c1724d0c70fbb9b",
+ "decrypt_command": "encryptly unpack diagnostic/build-1841e074.logd --password 28ff9c1724d0c70fbb9b",
+ "total_modules": 10,
+ "passed": 6,
+ "failed": 4,
+ "modules": [
+ {
+ "name": "backend",
+ "status": "FAIL",
+ "elapsed_seconds": 0.706,
+ "artifact": null,
+ "output": "\u001b[1m\u001b[92m Compiling\u001b[0m yoke v0.8.3\n\u001b[1m\u001b[92m Compiling\u001b[0m openssl-sys v0.9.117\n\u001b[1m\u001b[92m Compiling\u001b[0m futures-macro v0.3.32\n\u001b[1m\u001b[92m Compiling\u001b[0m icu_properties_data v2.2.0\n\u001b[1m\u001b[33mwarning\u001b[0m: openssl-sys@0.9.117: Could not find directory of OpenSSL installation, and this `-sys` crate cannot proceed without this knowledge. If OpenSSL is installed and this crate had trouble finding it, you can set the `OPENSSL_DIR` environment variable for the compilation process. See stderr section below for further information.\n\u001b[1m\u001b[91merror\u001b[0m: failed to run custom build command for `openssl-sys v0.9.117`\n\nCaused by:\n process didn't exit successfully: `/home/gautam/Desktop/zeroeye/backend/target/debug/build/openssl-sys-085d1b808c281a14/build-script-main` (exit status: 101)\n --- stdout\n cargo:rustc-check-cfg=cfg(osslconf, values(\"OPENSSL_NO_OCB\", \"OPENSSL_NO_SM4\", \"OPENSSL_NO_SEED\", \"OPENSSL_NO_CHACHA\", \"OPENSSL_NO_CAST\", \"OPENSSL_NO_IDEA\", \"OPENSSL_NO_CAMELLIA\", \"OPENSSL_NO_RC4\", \"OPENSSL_NO_BF\", \"OPENSSL_NO_PSK\", \"OPENSSL_NO_DEPRECATED_3_0\", \"OPENSSL_NO_SCRYPT\", \"OPENSSL_NO_SM3\", \"OPENSSL_NO_RMD160\", \"OPENSSL_NO_EC2M\", \"OPENSSL_NO_OCSP\", \"OPENSSL_NO_CMS\", \"OPENSSL_NO_COMP\", \"OPENSSL_NO_SOCK\", \"OPENSSL_NO_STDIO\", \"OPENSSL_NO_EC\", \"OPENSSL_NO_SSL3_METHOD\", \"OPENSSL_NO_KRB5\", \"OPENSSL_NO_TLSEXT\", \"OPENSSL_NO_SRP\", \"OPENSSL_NO_SRTP\", \"OPENSSL_NO_RFC3779\", \"OPENSSL_NO_SHA\", \"OPENSSL_NO_NEXTPROTONEG\", \"OPENSSL_NO_ENGINE\", \"OPENSSL_NO_BUF_FREELISTS\", \"OPENSSL_NO_RC2\"))\n cargo:rustc-check-cfg=cfg(openssl)\n cargo:rustc-check-cfg=cfg(libressl)\n cargo:rustc-check-cfg=cfg(boringssl)\n cargo:rustc-check-cfg=cfg(awslc)\n cargo:rustc-check-cfg=cfg(awslc_pregenerated)\n cargo:rustc-check-cfg=cfg(libressl250)\n cargo:rustc-check-cfg=cfg(libressl251)\n cargo:rustc-check-cfg=cfg(libressl252)\n cargo:rustc-check-cfg=cfg(libressl261)\n cargo:rustc-check-cfg=cfg(libressl270)\n cargo:rustc-check-cfg=cfg(libressl271)\n cargo:rustc-check-cfg=cfg(libressl273)\n cargo:rustc-check-cfg=cfg(libressl280)\n cargo:rustc-check-cfg=cfg(libressl281)\n cargo:rustc-check-cfg=cfg(libressl291)\n cargo:rustc-check-cfg=cfg(libressl310)\n cargo:rustc-check-cfg=cfg(libressl321)\n cargo:rustc-check-cfg=cfg(libressl332)\n cargo:rustc-check-cfg=cfg(libressl340)\n cargo:rustc-check-cfg=cfg(libressl350)\n cargo:rustc-check-cfg=cfg(libressl360)\n cargo:rustc-check-cfg=cfg(libressl361)\n cargo:rustc-check-cfg=cfg(libressl370)\n cargo:rustc-check-cfg=cfg(libressl380)\n cargo:rustc-check-cfg=cfg(libressl381)\n cargo:rustc-check-cfg=cfg(libressl382)\n cargo:rustc-check-cfg=cfg(libressl390)\n cargo:rustc-check-cfg=cfg(libressl400)\n cargo:rustc-check-cfg=cfg(libressl410)\n cargo:rustc-check-cfg=cfg(libressl420)\n cargo:rustc-check-cfg=cfg(libressl430)\n cargo:rustc-check-cfg=cfg(ossl101)\n cargo:rustc-check-cfg=cfg(ossl102)\n cargo:rustc-check-cfg=cfg(ossl102f)\n cargo:rustc-check-cfg=cfg(ossl102h)\n cargo:rustc-check-cfg=cfg(ossl110)\n cargo:rustc-check-cfg=cfg(ossl110f)\n cargo:rustc-check-cfg=cfg(ossl110g)\n cargo:rustc-check-cfg=cfg(ossl110h)\n cargo:rustc-check-cfg=cfg(ossl111)\n cargo:rustc-check-cfg=cfg(ossl111b)\n cargo:rustc-check-cfg=cfg(ossl111c)\n cargo:rustc-check-cfg=cfg(ossl111d)\n cargo:rustc-check-cfg=cfg(ossl300)\n cargo:rustc-check-cfg=cfg(ossl310)\n cargo:rustc-check-cfg=cfg(ossl320)\n cargo:rustc-check-cfg=cfg(ossl330)\n cargo:rustc-check-cfg=cfg(ossl340)\n cargo:rustc-check-cfg=cfg(ossl400)\n cargo:rerun-if-env-changed=X86_64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR\n X86_64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR unset\n cargo:rerun-if-env-changed=OPENSSL_LIB_DIR\n OPENSSL_LIB_DIR unset\n cargo:rerun-if-env-changed=X86_64_UNKNOWN_LINUX_GNU_OPENSSL_INCLUDE_DIR\n X86_64_UNKNOWN_LINUX_GNU_OPENSSL_INCLUDE_DIR unset\n cargo:rerun-if-env-changed=OPENSSL_INCLUDE_DIR\n OPENSSL_INCLUDE_DIR unset\n cargo:rerun-if-env-changed=X86_64_UNKNOWN_LINUX_GNU_OPENSSL_DIR\n X86_64_UNKNOWN_LINUX_GNU_OPENSSL_DIR unset\n cargo:rerun-if-env-changed=OPENSSL_DIR\n OPENSSL_DIR unset\n cargo:rerun-if-env-changed=OPENSSL_NO_PKG_CONFIG\n cargo:rerun-if-env-changed=PKG_CONFIG_x86_64-unknown-linux-gnu\n cargo:rerun-if-env-changed=PKG_CONFIG_x86_64_unknown_linux_gnu\n cargo:rerun-if-env-changed=HOST_PKG_CONFIG\n cargo:rerun-if-env-changed=PKG_CONFIG\n cargo:rerun-if-env-changed=OPENSSL_STATIC\n cargo:rerun-if-env-changed=OPENSSL_DYNAMIC\n cargo:rerun-if-env-changed=PKG_CONFIG_ALL_STATIC\n cargo:rerun-if-env-changed=PKG_CONFIG_ALL_DYNAMIC\n cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64-unknown-linux-gnu\n cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64_unknown_linux_gnu\n cargo:rerun-if-env-changed=HOST_PKG_CONFIG_PATH\n cargo:rerun-if-env-changed=PKG_CONFIG_PATH\n cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64-unknown-linux-gnu\n cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64_unknown_linux_gnu\n cargo:rerun-if-env-changed=HOST_PKG_CONFIG_LIBDIR\n cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR\n cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64-unknown-linux-gnu\n cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64_unknown_linux_gnu\n cargo:rerun-if-env-changed=HOST_PKG_CONFIG_SYSROOT_DIR\n cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR\n cargo:rerun-if-env-changed=OPENSSL_STATIC\n cargo:rerun-if-env-changed=OPENSSL_DYNAMIC\n cargo:rerun-if-env-changed=PKG_CONFIG_ALL_STATIC\n cargo:rerun-if-env-changed=PKG_CONFIG_ALL_DYNAMIC\n cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64-unknown-linux-gnu\n cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64_unknown_linux_gnu\n cargo:rerun-if-env-changed=HOST_PKG_CONFIG_PATH\n cargo:rerun-if-env-changed=PKG_CONFIG_PATH\n cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64-unknown-linux-gnu\n cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64_unknown_linux_gnu\n cargo:rerun-if-env-changed=HOST_PKG_CONFIG_LIBDIR\n cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR\n cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64-unknown-linux-gnu\n cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64_unknown_linux_gnu\n cargo:rerun-if-env-changed=HOST_PKG_CONFIG_SYSROOT_DIR\n cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR\n\n\n Could not find openssl via pkg-config:\n Could not run `PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1 pkg-config --libs --cflags openssl`\n The pkg-config command could not be found.\n\n Most likely, you need to install a pkg-config package for your OS.\n Try `apt install pkg-config`, or `yum install pkg-config`, or `brew install pkgconf`\n or `pkg install pkg-config`, or `apk add pkgconfig` depending on your distribution.\n\n If you've already installed it, ensure the pkg-config command is one of the\n directories in the PATH environment variable.\n\n If you did not expect this build to link to a pre-installed system library,\n then check documentation of the openssl-sys crate for an option to\n build the library from source, or disable features or dependencies\n that require pkg-config.\n\n cargo:warning=Could not find directory of OpenSSL installation, and this `-sys` crate cannot proceed without this knowledge. If OpenSSL is installed and this crate had trouble finding it, you can set the `OPENSSL_DIR` environment variable for the compilation process. See stderr section below for further information.\n\n --- stderr\n\n\n Could not find directory of OpenSSL installation, and this `-sys` crate cannot\n proceed without this knowledge. If OpenSSL is installed and this crate had\n trouble finding it, you can set the `OPENSSL_DIR` environment variable for the\n compilation process.\n\n Make sure you also have the development packages of openssl installed.\n For example, `libssl-dev` on Ubuntu or `openssl-devel` on Fedora.\n\n If you're in a situation where you think the directory *should* be found\n automatically, please open a bug at https://github.com/rust-openssl/rust-openssl\n and include information about your system as well as this message.\n\n $HOST = x86_64-unknown-linux-gnu\n $TARGET = x86_64-unknown-linux-gnu\n openssl-sys = 0.9.117\n\n\n It looks like you're compiling on Linux and also targeting Linux. Currently this\n requires the `pkg-config` utility to find OpenSSL but unfortunately `pkg-config`\n could not be found. If you have OpenSSL installed you can likely fix this by\n installing `pkg-config`.\n\n\n\u001b[1m\u001b[33mwarning\u001b[0m: build failed, waiting for other jobs to finish..."
+ },
+ {
+ "name": "frontend",
+ "status": "PASS",
+ "elapsed_seconds": 5.77,
+ "artifact": "/home/gautam/Desktop/zeroeye/frontend/dist",
+ "output": "> tent-frontend@0.0.0 build\n> tsc -b && vite build\n\nvite v6.4.3 building for production...\ntransforming...\n\u2713 100 modules transformed.\nrendering chunks...\ncomputing gzip size...\ndist/index.html 0.62 kB \u2502 gzip: 0.34 kB\ndist/assets/state-BkjSKDbY.js 8.91 kB \u2502 gzip: 3.54 kB \u2502 map: 57.15 kB\ndist/assets/vendor-CREcWLHI.js 48.93 kB \u2502 gzip: 17.25 kB \u2502 map: 481.27 kB\ndist/assets/index-CyxcoTyU.js 231.32 kB \u2502 gzip: 72.16 kB \u2502 map: 1,044.42 kB\n\u2713 built in 1.81s"
+ },
+ {
+ "name": "market",
+ "status": "PASS",
+ "elapsed_seconds": 0.591,
+ "artifact": "/home/gautam/Desktop/zeroeye/market/market",
+ "output": ""
+ },
+ {
+ "name": "frailbox",
+ "status": "PASS",
+ "elapsed_seconds": 0.004,
+ "artifact": "/home/gautam/Desktop/zeroeye/frailbox/frailbox",
+ "output": "make: Nothing to be done for 'all'."
+ },
+ {
+ "name": "engine",
+ "status": "PASS",
+ "elapsed_seconds": 0.096,
+ "artifact": "/home/gautam/Desktop/zeroeye/frailbox/engine/build/trial-engine",
+ "output": "[100%] Built target trial-engine"
+ },
+ {
+ "name": "compliance",
+ "status": "PASS",
+ "elapsed_seconds": 1.004,
+ "artifact": "/home/gautam/Desktop/zeroeye/compliance/build",
+ "output": "Note: ComplianceAuditor.java uses or overrides a deprecated API.\nNote: Recompile with -Xlint:deprecation for details."
+ },
+ {
+ "name": "v2-market-stream",
+ "status": "PASS",
+ "elapsed_seconds": 0.014,
+ "artifact": null,
+ "output": "Syntax OK"
+ },
+ {
+ "name": "nfc-scanner",
+ "status": "FAIL",
+ "elapsed_seconds": 0,
+ "artifact": null,
+ "output": "Command not found: [Errno 2] No such file or directory: 'luac'"
+ },
+ {
+ "name": "openapi-haskell",
+ "status": "FAIL",
+ "elapsed_seconds": 0.283,
+ "artifact": null,
+ "output": "[1 of 8] Compiling Network.HTTP.Types ( Network/HTTP/Types.hs, nothing )\n[2 of 8] Compiling Network.Wai ( Network/Wai.hs, nothing )\n[3 of 8] Compiling Network.Wai.Handler.Warp ( Network/Wai/Handler/Warp.hs, nothing )\n[4 of 8] Compiling Network.Wai.Logger ( Network/Wai/Logger.hs, nothing )\n[5 of 8] Compiling Tent.OpenAPI.Types ( Types.hs, /tmp/ghc44708_0/ghc_4.o, /tmp/ghc44708_0/ghc_4.dyn_o )\nTypes.hs:50:1: error: [GHC-61948]\n Could not find module \u2018Data.Aeson\u2019.\n Perhaps you meant Data.Version (from base-4.20.2.0)\n Use -v to see a list of the files searched for.\n |\n50 | import Data.Aeson (FromJSON(parseJSON), ToJSON(toJSON), Value(Object), (.!=), (.:?), (.=))\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:51:1: error: [GHC-87110]\n Could not find module \u2018Data.Aeson.Types\u2019.\n Use -v to see a list of the files searched for.\n |\n51 | import Data.Aeson.Types (Parser, parseMaybe)\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:71:1: error: [GHC-61948]\n Could not find module \u2018Data.Aeson\u2019.\n Perhaps you meant Data.Version (from base-4.20.2.0)\n Use -v to see a list of the files searched for.\n |\n71 | import qualified Data.Aeson as A\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:72:1: error: [GHC-87110]\n Could not find module \u2018Data.Aeson.Key\u2019.\n Use -v to see a list of the files searched for.\n |\n72 | import qualified Data.Aeson.Key as K\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:73:1: error: [GHC-87110]\n Could not find module \u2018Data.Aeson.KeyMap\u2019.\n Use -v to see a list of the files searched for.\n |\n73 | import qualified Data.Aeson.KeyMap as KM\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:74:1: error: [GHC-61948]\n Could not find module \u2018Data.HashMap.Strict\u2019.\n Perhaps you meant\n Data.Map.Strict (from containers-0.7)\n Data.IntMap.Strict (from containers-0.7)\n Use -v to see a list of the files searched for.\n |\n74 | import qualified Data.HashMap.Strict as HM\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:77:1: error: [GHC-87110]\n Could not find module \u2018Data.Yaml\u2019.\n Use -v to see a list of the files searched for.\n |\n77 | import qualified Data.Yaml as Y\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
+ },
+ {
+ "name": "openapi-tools",
+ "status": "FAIL",
+ "elapsed_seconds": 0,
+ "artifact": null,
+ "output": "Command not found: [Errno 2] No such file or directory: 'luac'"
+ }
+ ],
+ "pr_note": "Include the encrypted diagnostic logd artifact(s): diagnostic/build-1841e074.logd. The encrypted .logd is the required diagnostic content for PR review; this JSON file is metadata. Maintainers may ask you to remove these diagnostic artifacts before merging."
+}
diff --git a/diagnostic/build-1841e074.logd b/diagnostic/build-1841e074.logd
new file mode 100644
index 00000000..a782d14f
Binary files /dev/null and b/diagnostic/build-1841e074.logd differ
diff --git a/diagnostic/build-21b49191.json b/diagnostic/build-21b49191.json
new file mode 100644
index 00000000..f1fed28a
--- /dev/null
+++ b/diagnostic/build-21b49191.json
@@ -0,0 +1,87 @@
+{
+ "generated_at": "2026-06-18T10:46:08.798109+00:00",
+ "commit": "21b49191",
+ "diagnostic_logd": "diagnostic/build-21b49191.logd",
+ "diagnostic_logd_error": null,
+ "message_blocker": null,
+ "chunked": false,
+ "chunk_size_bytes": null,
+ "password": "bbdae6819a2fe729ef05",
+ "decrypt_command": "encryptly unpack diagnostic/build-21b49191.logd --password bbdae6819a2fe729ef05",
+ "total_modules": 10,
+ "passed": 7,
+ "failed": 3,
+ "modules": [
+ {
+ "name": "backend",
+ "status": "PASS",
+ "elapsed_seconds": 0.178,
+ "artifact": "/home/gautam/Desktop/zeroeye/backend/target",
+ "output": "\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `warn`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/embeddings.rs:28:28\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m28\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use tracing::{debug, info, warn};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(unused_imports)]` (part of `#[warn(unused)]`) on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `error`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:25:22\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m25\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use tracing::{debug, error, info, warn};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `error` and `warn`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/mod.rs:40:22\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m40\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use tracing::{debug, error, info, warn};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `c_int` and `c_uint`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:38:20\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m38\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::os::raw::{c_int, c_uint, c_ulong};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `std::ffi::CString`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/legacy.rs:35:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m35\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::ffi::CString;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `c_char`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/legacy.rs:36:20\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m36\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::os::raw::{c_char, c_ulong};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `CStr`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/types.rs:27:16\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m27\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::ffi::{CStr, CString};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `c_double` and `c_long`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/types.rs:29:28\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m29\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::os::raw::{c_char, c_double, c_int, c_uint, c_void, c_long, c_ulong};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `AtomicBool`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:14:25\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m14\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `EntityKind` and `legacy_normalize_phone_number`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/v1_compat.rs:8:47\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m8\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use crate::legacy::deprecations::{LegacyUuid, EntityKind, LegacyPagination, legacy_normalize_phone_number};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `super::ProtocolError`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/validate.rs:27:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m27\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use super::ProtocolError;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `MAX_MESSAGE_SIZE`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/codec.rs:25:38\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m25\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use crate::protocol::{ProtocolError, MAX_MESSAGE_SIZE, MIN_COMPATIBLE_VERSION, PROTOCOL_VERSION};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `Write`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/codec.rs:26:29\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m26\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::io::{Cursor, Read, Write};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `Ordering`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:25:36\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m25\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::sync::atomic::{AtomicU64, Ordering};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `Duration` and `Instant`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:27:17\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m27\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::time::{Duration, Instant};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `Deserialize` and `Serialize`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:28:13\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m28\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use serde::{Deserialize, Serialize};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `MAX_MESSAGE_SIZE`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:31:28\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m31\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use super::{ProtocolError, MAX_MESSAGE_SIZE, DEFAULT_TIMEOUT_MS};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `FrameDecoder` and `FrameEncoder`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:32:27\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m32\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use super::codec::{Frame, FrameEncoder, FrameDecoder, FLAG_REQUIRES_ACK};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: use of deprecated unit variant `legacy::deprecations::EntityKind::Team`: Teams are now Organizations. Use Organization instead.\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:244:25\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m244\u001b[0m \u001b[1m\u001b[94m|\u001b[0m EntityKind::Team => \"org\", // Legacy mapping\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(deprecated)]` on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: use of deprecated unit variant `legacy::deprecations::EntityKind::Project`: Projects were removed in the Platform v2 migration\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:245:25\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m245\u001b[0m \u001b[1m\u001b[94m|\u001b[0m EntityKind::Project => \"workspace\", // Legacy mapping\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: use of deprecated unit variant `legacy::deprecations::EntityKind::Team`: Teams are now Organizations. Use Organization instead.\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:266:25\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m266\u001b[0m \u001b[1m\u001b[94m|\u001b[0m EntityKind::Team\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: use of deprecated unit variant `legacy::deprecations::EntityKind::Project`: Projects were removed in the Platform v2 migration\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:267:31\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m267\u001b[0m \u001b[1m\u001b[94m|\u001b[0m | EntityKind::Project\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: variable does not need to be mutable\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:317:13\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m317\u001b[0m \u001b[1m\u001b[94m|\u001b[0m let mut buffer = unsafe { &mut *c_buffer };\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m----\u001b[0m\u001b[1m\u001b[33m^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94mhelp: remove this `mut`\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(unused_mut)]` (part of `#[warn(unused)]`) on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused variable: `initialized`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:440:13\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m440\u001b[0m \u001b[1m\u001b[94m|\u001b[0m let initialized = Arc::new(AtomicBool::new(true));\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33mhelp: if this is intentional, prefix it with an underscore: `_initialized`\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(unused_variables)]` (part of `#[warn(unused)]`) on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: variable does not need to be mutable\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/legacy.rs:267:13\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m267\u001b[0m \u001b[1m\u001b[94m|\u001b[0m let mut buffer = unsafe { &mut *c_buffer };\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m----\u001b[0m\u001b[1m\u001b[33m^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94mhelp: remove this `mut`\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused variable: `value`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:508:15\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m508\u001b[0m \u001b[1m\u001b[94m|\u001b[0m for (key, value) in configs {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m \u001b[1m\u001b[33mhelp: if this is intentional, prefix it with an underscore: `_value`\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused variable: `obj`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/validate.rs:282:25\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m282\u001b[0m \u001b[1m\u001b[94m|\u001b[0m if let Some(obj) = value.as_object() {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^\u001b[0m \u001b[1m\u001b[33mhelp: if this is intentional, prefix it with an underscore: `_obj`\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: type `BridgeStats` is more private than the item `ConnectorBridge::stats`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:415:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m415\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub fn stats(&self) -> BridgeStats {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33mmethod `ConnectorBridge::stats` is reachable at visibility `pub`\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[92mnote\u001b[0m: but type `BridgeStats` is only usable at visibility `pub(self)`\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:225:1\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m225\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct BridgeStats {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[92m^^^^^^^^^^^^^^^^^^\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(private_interfaces)]` on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: type `CircuitState` is more private than the item `ConnectorBridge::circuit_state`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:423:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m423\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub fn circuit_state(&self) -> CircuitState {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33mmethod `ConnectorBridge::circuit_state` is reachable at visibility `pub`\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[92mnote\u001b[0m: but type `CircuitState` is only usable at visibility `pub(self)`\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:79:1\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m 79\u001b[0m \u001b[1m\u001b[94m|\u001b[0m enum CircuitState {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[92m^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `NCP_TEMPERATURE` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/mod.rs:53:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m53\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const NCP_TEMPERATURE: f64 = 0.42;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `MIN_CONFIDENCE_THRESHOLD` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/mod.rs:61:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m61\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const MIN_CONFIDENCE_THRESHOLD: f64 = 0.65;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `MAX_INFERENCE_RETRIES` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/mod.rs:65:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m65\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const MAX_INFERENCE_RETRIES: u32 = 5;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: fields `discovery`, `broker`, and `registry` are never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/mod.rs:173:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m171\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct AiOrchestrator {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m--------------\u001b[0m \u001b[1m\u001b[94mfields in this struct\u001b[0m\n\u001b[1m\u001b[94m172\u001b[0m \u001b[1m\u001b[94m|\u001b[0m /// Reference to the service discovery subsystem\n\u001b[1m\u001b[94m173\u001b[0m \u001b[1m\u001b[94m|\u001b[0m discovery: Arc>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m174\u001b[0m \u001b[1m\u001b[94m|\u001b[0m /// Reference to the message broker subsystem\n\u001b[1m\u001b[94m175\u001b[0m \u001b[1m\u001b[94m|\u001b[0m broker: Arc>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\u001b[1m\u001b[94m176\u001b[0m \u001b[1m\u001b[94m|\u001b[0m /// Reference to the service registry subsystem\n\u001b[1m\u001b[94m177\u001b[0m \u001b[1m\u001b[94m|\u001b[0m registry: Arc>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `window_start` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/embeddings.rs:661:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m658\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct ContextWindowManager {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m--------------------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m661\u001b[0m \u001b[1m\u001b[94m|\u001b[0m window_start: Instant,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `MAX_RETRIES` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:41:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m41\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const MAX_RETRIES: u32 = 3;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `RETRY_BASE_DELAY_MS` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:44:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m44\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const RETRY_BASE_DELAY_MS: u64 = 1000;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: fields `api_key`, `base_url`, and `client` are never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:453:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m452\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct AnthropicClient {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------------\u001b[0m \u001b[1m\u001b[94mfields in this struct\u001b[0m\n\u001b[1m\u001b[94m453\u001b[0m \u001b[1m\u001b[94m|\u001b[0m api_key: String,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m454\u001b[0m \u001b[1m\u001b[94m|\u001b[0m base_url: String,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m455\u001b[0m \u001b[1m\u001b[94m|\u001b[0m models: Vec,\n\u001b[1m\u001b[94m456\u001b[0m \u001b[1m\u001b[94m|\u001b[0m client: reqwest::Client,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `AnthropicClient` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `routing_table` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:719:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m716\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct ModelRouter {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m-----------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m719\u001b[0m \u001b[1m\u001b[94m|\u001b[0m routing_table: RwLock>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `ModelRouter` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `cost_history` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:951:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m947\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct TokenCounter {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m------------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m951\u001b[0m \u001b[1m\u001b[94m|\u001b[0m cost_history: RwLock>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `HEALTH_CHECK_TIMEOUT_MS` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:64:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m64\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const HEALTH_CHECK_TIMEOUT_MS: u64 = 1000;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `id` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:152:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m151\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct PoolEntry {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m152\u001b[0m \u001b[1m\u001b[94m|\u001b[0m id: usize,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: method `stats` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:195:8\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m163\u001b[0m \u001b[1m\u001b[94m|\u001b[0m impl ConnectionPool {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m-------------------\u001b[0m \u001b[1m\u001b[94mmethod in this implementation\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m195\u001b[0m \u001b[1m\u001b[94m|\u001b[0m fn stats(&self) -> PoolStats {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: struct `PoolStats` is never constructed\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:203:8\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m203\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct PoolStats {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: fields `circuit_breaker_trips` and `health_check_failures` are never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:229:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m225\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct BridgeStats {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m-----------\u001b[0m \u001b[1m\u001b[94mfields in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m229\u001b[0m \u001b[1m\u001b[94m|\u001b[0m circuit_breaker_trips: u64,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m230\u001b[0m \u001b[1m\u001b[94m|\u001b[0m health_check_failures: u64,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `BridgeStats` has derived impls for the traits `Clone` and `Debug`, but these are intentionally ignored during dead code analysis\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `consumers` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/messaging/mod.rs:38:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m35\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct MessageBroker {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m-------------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m38\u001b[0m \u001b[1m\u001b[94m|\u001b[0m consumers: DashMap>>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `version` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/messages.rs:293:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m291\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct MessageRegistry {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m292\u001b[0m \u001b[1m\u001b[94m|\u001b[0m handlers: HashMap,\n\u001b[1m\u001b[94m293\u001b[0m \u001b[1m\u001b[94m|\u001b[0m version: u32,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `version` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/serialize.rs:258:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m255\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct Schema {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m258\u001b[0m \u001b[1m\u001b[94m|\u001b[0m version: u32,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: fields `required` and `default_value` are never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/serialize.rs:264:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m261\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct SchemaField {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m-----------\u001b[0m \u001b[1m\u001b[94mfields in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m264\u001b[0m \u001b[1m\u001b[94m|\u001b[0m required: bool,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m265\u001b[0m \u001b[1m\u001b[94m|\u001b[0m default_value: Option,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: variant `Custom` is never constructed\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/serialize.rs:276:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m269\u001b[0m \u001b[1m\u001b[94m|\u001b[0m enum FieldValidation {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------------\u001b[0m \u001b[1m\u001b[94mvariant in this enum\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m276\u001b[0m \u001b[1m\u001b[94m|\u001b[0m Custom(String),\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: fields `next_request_id`, `pending_requests`, `serializer`, and `timeout_ms` are never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:218:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m217\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct RpcClient {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------\u001b[0m \u001b[1m\u001b[94mfields in this struct\u001b[0m\n\u001b[1m\u001b[94m218\u001b[0m \u001b[1m\u001b[94m|\u001b[0m next_request_id: AtomicU64,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m219\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pending_requests: Arc, RpcError>>>>>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m220\u001b[0m \u001b[1m\u001b[94m|\u001b[0m serializer: Serializer,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m221\u001b[0m \u001b[1m\u001b[94m|\u001b[0m timeout_ms: u64,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `serializer` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:271:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m269\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct RpcServer {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m270\u001b[0m \u001b[1m\u001b[94m|\u001b[0m handlers: HashMap,\n\u001b[1m\u001b[94m271\u001b[0m \u001b[1m\u001b[94m|\u001b[0m serializer: Serializer,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `events` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/registry/mod.rs:31:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m28\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct ServiceRegistry {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m31\u001b[0m \u001b[1m\u001b[94m|\u001b[0m events: Arc>>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m: `tent-backend` (lib) generated 52 warnings (run `cargo fix --lib -p tent-backend` to apply 23 suggestions)\n\u001b[1m\u001b[92m Finished\u001b[0m `dev` profile [unoptimized + debuginfo] target(s) in 0.14s"
+ },
+ {
+ "name": "frontend",
+ "status": "PASS",
+ "elapsed_seconds": 5.869,
+ "artifact": "/home/gautam/Desktop/zeroeye/frontend/dist",
+ "output": "> tent-frontend@0.0.0 build\n> tsc -b && vite build\n\nvite v6.4.3 building for production...\ntransforming...\n\u2713 100 modules transformed.\nrendering chunks...\ncomputing gzip size...\ndist/index.html 0.62 kB \u2502 gzip: 0.34 kB\ndist/assets/state-BkjSKDbY.js 8.91 kB \u2502 gzip: 3.54 kB \u2502 map: 57.15 kB\ndist/assets/vendor-CREcWLHI.js 48.93 kB \u2502 gzip: 17.25 kB \u2502 map: 481.27 kB\ndist/assets/index-CyxcoTyU.js 231.32 kB \u2502 gzip: 72.16 kB \u2502 map: 1,044.42 kB\n\u2713 built in 1.86s"
+ },
+ {
+ "name": "market",
+ "status": "PASS",
+ "elapsed_seconds": 0.589,
+ "artifact": "/home/gautam/Desktop/zeroeye/market/market",
+ "output": ""
+ },
+ {
+ "name": "frailbox",
+ "status": "PASS",
+ "elapsed_seconds": 0.003,
+ "artifact": "/home/gautam/Desktop/zeroeye/frailbox/frailbox",
+ "output": "make: Nothing to be done for 'all'."
+ },
+ {
+ "name": "engine",
+ "status": "PASS",
+ "elapsed_seconds": 0.096,
+ "artifact": "/home/gautam/Desktop/zeroeye/frailbox/engine/build/trial-engine",
+ "output": "[100%] Built target trial-engine"
+ },
+ {
+ "name": "compliance",
+ "status": "PASS",
+ "elapsed_seconds": 1.062,
+ "artifact": "/home/gautam/Desktop/zeroeye/compliance/build",
+ "output": "Note: ComplianceAuditor.java uses or overrides a deprecated API.\nNote: Recompile with -Xlint:deprecation for details."
+ },
+ {
+ "name": "v2-market-stream",
+ "status": "PASS",
+ "elapsed_seconds": 0.014,
+ "artifact": null,
+ "output": "Syntax OK"
+ },
+ {
+ "name": "nfc-scanner",
+ "status": "FAIL",
+ "elapsed_seconds": 0,
+ "artifact": null,
+ "output": "Command not found: [Errno 2] No such file or directory: 'luac'"
+ },
+ {
+ "name": "openapi-haskell",
+ "status": "FAIL",
+ "elapsed_seconds": 0.307,
+ "artifact": null,
+ "output": "[1 of 8] Compiling Network.HTTP.Types ( Network/HTTP/Types.hs, nothing )\n[2 of 8] Compiling Network.Wai ( Network/Wai.hs, nothing )\n[3 of 8] Compiling Network.Wai.Handler.Warp ( Network/Wai/Handler/Warp.hs, nothing )\n[4 of 8] Compiling Network.Wai.Logger ( Network/Wai/Logger.hs, nothing )\n[5 of 8] Compiling Tent.OpenAPI.Types ( Types.hs, /tmp/ghc72877_0/ghc_4.o, /tmp/ghc72877_0/ghc_4.dyn_o )\nTypes.hs:50:1: error: [GHC-61948]\n Could not find module \u2018Data.Aeson\u2019.\n Perhaps you meant Data.Version (from base-4.20.2.0)\n Use -v to see a list of the files searched for.\n |\n50 | import Data.Aeson (FromJSON(parseJSON), ToJSON(toJSON), Value(Object), (.!=), (.:?), (.=))\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:51:1: error: [GHC-87110]\n Could not find module \u2018Data.Aeson.Types\u2019.\n Use -v to see a list of the files searched for.\n |\n51 | import Data.Aeson.Types (Parser, parseMaybe)\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:71:1: error: [GHC-61948]\n Could not find module \u2018Data.Aeson\u2019.\n Perhaps you meant Data.Version (from base-4.20.2.0)\n Use -v to see a list of the files searched for.\n |\n71 | import qualified Data.Aeson as A\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:72:1: error: [GHC-87110]\n Could not find module \u2018Data.Aeson.Key\u2019.\n Use -v to see a list of the files searched for.\n |\n72 | import qualified Data.Aeson.Key as K\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:73:1: error: [GHC-87110]\n Could not find module \u2018Data.Aeson.KeyMap\u2019.\n Use -v to see a list of the files searched for.\n |\n73 | import qualified Data.Aeson.KeyMap as KM\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:74:1: error: [GHC-61948]\n Could not find module \u2018Data.HashMap.Strict\u2019.\n Perhaps you meant\n Data.Map.Strict (from containers-0.7)\n Data.IntMap.Strict (from containers-0.7)\n Use -v to see a list of the files searched for.\n |\n74 | import qualified Data.HashMap.Strict as HM\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:77:1: error: [GHC-87110]\n Could not find module \u2018Data.Yaml\u2019.\n Use -v to see a list of the files searched for.\n |\n77 | import qualified Data.Yaml as Y\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
+ },
+ {
+ "name": "openapi-tools",
+ "status": "FAIL",
+ "elapsed_seconds": 0,
+ "artifact": null,
+ "output": "Command not found: [Errno 2] No such file or directory: 'luac'"
+ }
+ ],
+ "pr_note": "Include the encrypted diagnostic logd artifact(s): diagnostic/build-21b49191.logd. The encrypted .logd is the required diagnostic content for PR review; this JSON file is metadata. Maintainers may ask you to remove these diagnostic artifacts before merging."
+}
diff --git a/diagnostic/build-21b49191.logd b/diagnostic/build-21b49191.logd
new file mode 100644
index 00000000..8eea7c9f
Binary files /dev/null and b/diagnostic/build-21b49191.logd differ
diff --git a/diagnostic/build-cf54f059.json b/diagnostic/build-cf54f059.json
new file mode 100644
index 00000000..36234da6
--- /dev/null
+++ b/diagnostic/build-cf54f059.json
@@ -0,0 +1,87 @@
+{
+ "generated_at": "2026-06-19T06:44:22.618609+00:00",
+ "commit": "cf54f059",
+ "diagnostic_logd": "diagnostic/build-cf54f059.logd",
+ "diagnostic_logd_error": null,
+ "message_blocker": null,
+ "chunked": false,
+ "chunk_size_bytes": null,
+ "password": "4f80c64ede5bfe9d0426",
+ "decrypt_command": "encryptly unpack diagnostic/build-cf54f059.logd --password 4f80c64ede5bfe9d0426",
+ "total_modules": 10,
+ "passed": 9,
+ "failed": 1,
+ "modules": [
+ {
+ "name": "backend",
+ "status": "PASS",
+ "elapsed_seconds": 0.695,
+ "artifact": "/tmp/repos/Kickama/backend/target",
+ "output": "\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `warn`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/embeddings.rs:28:28\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m28\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use tracing::{debug, info, warn};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(unused_imports)]` (part of `#[warn(unused)]`) on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `error`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:25:22\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m25\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use tracing::{debug, error, info, warn};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `error` and `warn`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/mod.rs:40:22\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m40\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use tracing::{debug, error, info, warn};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `c_int` and `c_uint`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:38:20\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m38\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::os::raw::{c_int, c_uint, c_ulong};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `std::ffi::CString`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/legacy.rs:35:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m35\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::ffi::CString;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `c_char`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/legacy.rs:36:20\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m36\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::os::raw::{c_char, c_ulong};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `CStr`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/types.rs:27:16\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m27\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::ffi::{CStr, CString};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `c_double` and `c_long`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/types.rs:29:28\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m29\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::os::raw::{c_char, c_double, c_int, c_uint, c_void, c_long, c_ulong};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `AtomicBool`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:14:25\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m14\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `EntityKind` and `legacy_normalize_phone_number`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/v1_compat.rs:8:47\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m8\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use crate::legacy::deprecations::{LegacyUuid, EntityKind, LegacyPagination, legacy_normalize_phone_number};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `super::ProtocolError`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/validate.rs:27:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m27\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use super::ProtocolError;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `MAX_MESSAGE_SIZE`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/codec.rs:25:38\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m25\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use crate::protocol::{ProtocolError, MAX_MESSAGE_SIZE, MIN_COMPATIBLE_VERSION, PROTOCOL_VERSION};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `Write`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/codec.rs:26:29\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m26\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::io::{Cursor, Read, Write};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `Ordering`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:25:36\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m25\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::sync::atomic::{AtomicU64, Ordering};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `Duration` and `Instant`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:27:17\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m27\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::time::{Duration, Instant};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `Deserialize` and `Serialize`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:28:13\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m28\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use serde::{Deserialize, Serialize};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `MAX_MESSAGE_SIZE`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:31:28\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m31\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use super::{ProtocolError, MAX_MESSAGE_SIZE, DEFAULT_TIMEOUT_MS};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `FrameDecoder` and `FrameEncoder`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:32:27\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m32\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use super::codec::{Frame, FrameEncoder, FrameDecoder, FLAG_REQUIRES_ACK};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: use of deprecated unit variant `legacy::deprecations::EntityKind::Team`: Teams are now Organizations. Use Organization instead.\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:244:25\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m244\u001b[0m \u001b[1m\u001b[94m|\u001b[0m EntityKind::Team => \"org\", // Legacy mapping\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(deprecated)]` on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: use of deprecated unit variant `legacy::deprecations::EntityKind::Project`: Projects were removed in the Platform v2 migration\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:245:25\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m245\u001b[0m \u001b[1m\u001b[94m|\u001b[0m EntityKind::Project => \"workspace\", // Legacy mapping\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: use of deprecated unit variant `legacy::deprecations::EntityKind::Team`: Teams are now Organizations. Use Organization instead.\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:266:25\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m266\u001b[0m \u001b[1m\u001b[94m|\u001b[0m EntityKind::Team\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: use of deprecated unit variant `legacy::deprecations::EntityKind::Project`: Projects were removed in the Platform v2 migration\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:267:31\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m267\u001b[0m \u001b[1m\u001b[94m|\u001b[0m | EntityKind::Project\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: variable does not need to be mutable\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:317:13\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m317\u001b[0m \u001b[1m\u001b[94m|\u001b[0m let mut buffer = unsafe { &mut *c_buffer };\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m----\u001b[0m\u001b[1m\u001b[33m^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94mhelp: remove this `mut`\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(unused_mut)]` (part of `#[warn(unused)]`) on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused variable: `initialized`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:440:13\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m440\u001b[0m \u001b[1m\u001b[94m|\u001b[0m let initialized = Arc::new(AtomicBool::new(true));\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33mhelp: if this is intentional, prefix it with an underscore: `_initialized`\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(unused_variables)]` (part of `#[warn(unused)]`) on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: variable does not need to be mutable\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/legacy.rs:267:13\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m267\u001b[0m \u001b[1m\u001b[94m|\u001b[0m let mut buffer = unsafe { &mut *c_buffer };\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m----\u001b[0m\u001b[1m\u001b[33m^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94mhelp: remove this `mut`\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused variable: `value`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:508:15\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m508\u001b[0m \u001b[1m\u001b[94m|\u001b[0m for (key, value) in configs {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m \u001b[1m\u001b[33mhelp: if this is intentional, prefix it with an underscore: `_value`\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused variable: `obj`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/validate.rs:282:25\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m282\u001b[0m \u001b[1m\u001b[94m|\u001b[0m if let Some(obj) = value.as_object() {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^\u001b[0m \u001b[1m\u001b[33mhelp: if this is intentional, prefix it with an underscore: `_obj`\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: type `BridgeStats` is more private than the item `ConnectorBridge::stats`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:415:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m415\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub fn stats(&self) -> BridgeStats {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33mmethod `ConnectorBridge::stats` is reachable at visibility `pub`\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[92mnote\u001b[0m: but type `BridgeStats` is only usable at visibility `pub(self)`\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:225:1\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m225\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct BridgeStats {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[92m^^^^^^^^^^^^^^^^^^\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(private_interfaces)]` on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: type `CircuitState` is more private than the item `ConnectorBridge::circuit_state`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:423:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m423\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub fn circuit_state(&self) -> CircuitState {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33mmethod `ConnectorBridge::circuit_state` is reachable at visibility `pub`\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[92mnote\u001b[0m: but type `CircuitState` is only usable at visibility `pub(self)`\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:79:1\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m 79\u001b[0m \u001b[1m\u001b[94m|\u001b[0m enum CircuitState {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[92m^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `NCP_TEMPERATURE` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/mod.rs:53:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m53\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const NCP_TEMPERATURE: f64 = 0.42;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `MIN_CONFIDENCE_THRESHOLD` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/mod.rs:61:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m61\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const MIN_CONFIDENCE_THRESHOLD: f64 = 0.65;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `MAX_INFERENCE_RETRIES` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/mod.rs:65:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m65\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const MAX_INFERENCE_RETRIES: u32 = 5;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: fields `discovery`, `broker`, and `registry` are never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/mod.rs:173:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m171\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct AiOrchestrator {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m--------------\u001b[0m \u001b[1m\u001b[94mfields in this struct\u001b[0m\n\u001b[1m\u001b[94m172\u001b[0m \u001b[1m\u001b[94m|\u001b[0m /// Reference to the service discovery subsystem\n\u001b[1m\u001b[94m173\u001b[0m \u001b[1m\u001b[94m|\u001b[0m discovery: Arc>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m174\u001b[0m \u001b[1m\u001b[94m|\u001b[0m /// Reference to the message broker subsystem\n\u001b[1m\u001b[94m175\u001b[0m \u001b[1m\u001b[94m|\u001b[0m broker: Arc>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\u001b[1m\u001b[94m176\u001b[0m \u001b[1m\u001b[94m|\u001b[0m /// Reference to the service registry subsystem\n\u001b[1m\u001b[94m177\u001b[0m \u001b[1m\u001b[94m|\u001b[0m registry: Arc>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `window_start` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/embeddings.rs:661:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m658\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct ContextWindowManager {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m--------------------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m661\u001b[0m \u001b[1m\u001b[94m|\u001b[0m window_start: Instant,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `MAX_RETRIES` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:41:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m41\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const MAX_RETRIES: u32 = 3;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `RETRY_BASE_DELAY_MS` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:44:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m44\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const RETRY_BASE_DELAY_MS: u64 = 1000;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: fields `api_key`, `base_url`, and `client` are never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:453:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m452\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct AnthropicClient {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------------\u001b[0m \u001b[1m\u001b[94mfields in this struct\u001b[0m\n\u001b[1m\u001b[94m453\u001b[0m \u001b[1m\u001b[94m|\u001b[0m api_key: String,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m454\u001b[0m \u001b[1m\u001b[94m|\u001b[0m base_url: String,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m455\u001b[0m \u001b[1m\u001b[94m|\u001b[0m models: Vec,\n\u001b[1m\u001b[94m456\u001b[0m \u001b[1m\u001b[94m|\u001b[0m client: reqwest::Client,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `AnthropicClient` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `routing_table` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:719:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m716\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct ModelRouter {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m-----------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m719\u001b[0m \u001b[1m\u001b[94m|\u001b[0m routing_table: RwLock>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `ModelRouter` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `cost_history` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:951:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m947\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct TokenCounter {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m------------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m951\u001b[0m \u001b[1m\u001b[94m|\u001b[0m cost_history: RwLock>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `HEALTH_CHECK_TIMEOUT_MS` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:64:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m64\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const HEALTH_CHECK_TIMEOUT_MS: u64 = 1000;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `id` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:152:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m151\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct PoolEntry {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m152\u001b[0m \u001b[1m\u001b[94m|\u001b[0m id: usize,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: method `stats` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:195:8\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m163\u001b[0m \u001b[1m\u001b[94m|\u001b[0m impl ConnectionPool {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m-------------------\u001b[0m \u001b[1m\u001b[94mmethod in this implementation\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m195\u001b[0m \u001b[1m\u001b[94m|\u001b[0m fn stats(&self) -> PoolStats {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: struct `PoolStats` is never constructed\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:203:8\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m203\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct PoolStats {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: fields `circuit_breaker_trips` and `health_check_failures` are never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:229:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m225\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct BridgeStats {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m-----------\u001b[0m \u001b[1m\u001b[94mfields in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m229\u001b[0m \u001b[1m\u001b[94m|\u001b[0m circuit_breaker_trips: u64,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m230\u001b[0m \u001b[1m\u001b[94m|\u001b[0m health_check_failures: u64,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `BridgeStats` has derived impls for the traits `Clone` and `Debug`, but these are intentionally ignored during dead code analysis\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `consumers` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/messaging/mod.rs:38:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m35\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct MessageBroker {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m-------------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m38\u001b[0m \u001b[1m\u001b[94m|\u001b[0m consumers: DashMap>>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `version` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/messages.rs:293:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m291\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct MessageRegistry {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m292\u001b[0m \u001b[1m\u001b[94m|\u001b[0m handlers: HashMap,\n\u001b[1m\u001b[94m293\u001b[0m \u001b[1m\u001b[94m|\u001b[0m version: u32,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `version` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/serialize.rs:258:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m255\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct Schema {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m258\u001b[0m \u001b[1m\u001b[94m|\u001b[0m version: u32,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: fields `required` and `default_value` are never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/serialize.rs:264:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m261\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct SchemaField {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m-----------\u001b[0m \u001b[1m\u001b[94mfields in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m264\u001b[0m \u001b[1m\u001b[94m|\u001b[0m required: bool,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m265\u001b[0m \u001b[1m\u001b[94m|\u001b[0m default_value: Option,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: variant `Custom` is never constructed\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/serialize.rs:276:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m269\u001b[0m \u001b[1m\u001b[94m|\u001b[0m enum FieldValidation {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------------\u001b[0m \u001b[1m\u001b[94mvariant in this enum\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m276\u001b[0m \u001b[1m\u001b[94m|\u001b[0m Custom(String),\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: fields `next_request_id`, `pending_requests`, `serializer`, and `timeout_ms` are never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:218:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m217\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct RpcClient {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------\u001b[0m \u001b[1m\u001b[94mfields in this struct\u001b[0m\n\u001b[1m\u001b[94m218\u001b[0m \u001b[1m\u001b[94m|\u001b[0m next_request_id: AtomicU64,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m219\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pending_requests: Arc, RpcError>>>>>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m220\u001b[0m \u001b[1m\u001b[94m|\u001b[0m serializer: Serializer,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m221\u001b[0m \u001b[1m\u001b[94m|\u001b[0m timeout_ms: u64,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `serializer` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:271:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m269\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct RpcServer {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m270\u001b[0m \u001b[1m\u001b[94m|\u001b[0m handlers: HashMap,\n\u001b[1m\u001b[94m271\u001b[0m \u001b[1m\u001b[94m|\u001b[0m serializer: Serializer,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `events` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/registry/mod.rs:31:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m28\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct ServiceRegistry {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m31\u001b[0m \u001b[1m\u001b[94m|\u001b[0m events: Arc>>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m: `tent-backend` (lib) generated 52 warnings (run `cargo fix --lib -p tent-backend` to apply 23 suggestions)\n\u001b[1m\u001b[92m Finished\u001b[0m `dev` profile [unoptimized + debuginfo] target(s) in 0.64s"
+ },
+ {
+ "name": "frontend",
+ "status": "PASS",
+ "elapsed_seconds": 8.369,
+ "artifact": "/tmp/repos/Kickama/frontend/dist",
+ "output": "> tent-frontend@0.0.0 build\n> tsc -b && vite build\n\nvite v6.4.3 building for production...\ntransforming...\n\u2713 100 modules transformed.\nrendering chunks...\ncomputing gzip size...\ndist/index.html 0.62 kB \u2502 gzip: 0.34 kB\ndist/assets/state-BkjSKDbY.js 8.91 kB \u2502 gzip: 3.54 kB \u2502 map: 57.15 kB\ndist/assets/vendor-CREcWLHI.js 48.93 kB \u2502 gzip: 17.25 kB \u2502 map: 481.27 kB\ndist/assets/index-CyxcoTyU.js 231.32 kB \u2502 gzip: 72.16 kB \u2502 map: 1,044.42 kB\n\u2713 built in 2.52s"
+ },
+ {
+ "name": "market",
+ "status": "PASS",
+ "elapsed_seconds": 0.947,
+ "artifact": "/tmp/repos/Kickama/market/market",
+ "output": ""
+ },
+ {
+ "name": "frailbox",
+ "status": "PASS",
+ "elapsed_seconds": 0.004,
+ "artifact": "/tmp/repos/Kickama/frailbox/frailbox",
+ "output": "make: Nothing to be done for 'all'."
+ },
+ {
+ "name": "engine",
+ "status": "PASS",
+ "elapsed_seconds": 0.146,
+ "artifact": "/tmp/repos/Kickama/frailbox/engine/build/trial-engine",
+ "output": "[100%] Built target trial-engine"
+ },
+ {
+ "name": "compliance",
+ "status": "PASS",
+ "elapsed_seconds": 1.472,
+ "artifact": "/tmp/repos/Kickama/compliance/build",
+ "output": "Note: ComplianceAuditor.java uses or overrides a deprecated API.\nNote: Recompile with -Xlint:deprecation for details."
+ },
+ {
+ "name": "v2-market-stream",
+ "status": "PASS",
+ "elapsed_seconds": 0.019,
+ "artifact": null,
+ "output": "Syntax OK"
+ },
+ {
+ "name": "nfc-scanner",
+ "status": "PASS",
+ "elapsed_seconds": 0.003,
+ "artifact": null,
+ "output": ""
+ },
+ {
+ "name": "openapi-haskell",
+ "status": "FAIL",
+ "elapsed_seconds": 0.455,
+ "artifact": null,
+ "output": "[1 of 8] Compiling Network.HTTP.Types ( Network/HTTP/Types.hs, nothing )\n[2 of 8] Compiling Network.Wai ( Network/Wai.hs, nothing )\n[3 of 8] Compiling Network.Wai.Handler.Warp ( Network/Wai/Handler/Warp.hs, nothing )\n[4 of 8] Compiling Network.Wai.Logger ( Network/Wai/Logger.hs, nothing )\n[5 of 8] Compiling Tent.OpenAPI.Types ( Types.hs, /tmp/ghc53988_0/ghc_4.o, /tmp/ghc53988_0/ghc_4.dyn_o )\nTypes.hs:50:1: error: [GHC-61948]\n Could not find module \u2018Data.Aeson\u2019.\n Perhaps you meant Data.Version (from base-4.20.2.0)\n Use -v to see a list of the files searched for.\n |\n50 | import Data.Aeson (FromJSON(parseJSON), ToJSON(toJSON), Value(Object), (.!=), (.:?), (.=))\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:51:1: error: [GHC-87110]\n Could not find module \u2018Data.Aeson.Types\u2019.\n Use -v to see a list of the files searched for.\n |\n51 | import Data.Aeson.Types (Parser, parseMaybe)\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:71:1: error: [GHC-61948]\n Could not find module \u2018Data.Aeson\u2019.\n Perhaps you meant Data.Version (from base-4.20.2.0)\n Use -v to see a list of the files searched for.\n |\n71 | import qualified Data.Aeson as A\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:72:1: error: [GHC-87110]\n Could not find module \u2018Data.Aeson.Key\u2019.\n Use -v to see a list of the files searched for.\n |\n72 | import qualified Data.Aeson.Key as K\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:73:1: error: [GHC-87110]\n Could not find module \u2018Data.Aeson.KeyMap\u2019.\n Use -v to see a list of the files searched for.\n |\n73 | import qualified Data.Aeson.KeyMap as KM\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:74:1: error: [GHC-61948]\n Could not find module \u2018Data.HashMap.Strict\u2019.\n Perhaps you meant\n Data.Map.Strict (from containers-0.7)\n Data.IntMap.Strict (from containers-0.7)\n Use -v to see a list of the files searched for.\n |\n74 | import qualified Data.HashMap.Strict as HM\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:77:1: error: [GHC-87110]\n Could not find module \u2018Data.Yaml\u2019.\n Use -v to see a list of the files searched for.\n |\n77 | import qualified Data.Yaml as Y\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
+ },
+ {
+ "name": "openapi-tools",
+ "status": "PASS",
+ "elapsed_seconds": 0.004,
+ "artifact": null,
+ "output": ""
+ }
+ ],
+ "pr_note": "Include the encrypted diagnostic logd artifact(s): diagnostic/build-cf54f059.logd. The encrypted .logd is the required diagnostic content for PR review; this JSON file is metadata. Maintainers may ask you to remove these diagnostic artifacts before merging."
+}
diff --git a/diagnostic/build-cf54f059.logd b/diagnostic/build-cf54f059.logd
new file mode 100644
index 00000000..76872adc
Binary files /dev/null and b/diagnostic/build-cf54f059.logd differ
diff --git a/diagnostic/build-f8536a91.json b/diagnostic/build-f8536a91.json
new file mode 100644
index 00000000..dfb17b2e
--- /dev/null
+++ b/diagnostic/build-f8536a91.json
@@ -0,0 +1,87 @@
+{
+ "generated_at": "2026-06-19T06:30:02.464132+00:00",
+ "commit": "f8536a91",
+ "diagnostic_logd": "diagnostic/build-f8536a91.logd",
+ "diagnostic_logd_error": null,
+ "message_blocker": null,
+ "chunked": false,
+ "chunk_size_bytes": null,
+ "password": "72ac58222d618b5b917b",
+ "decrypt_command": "encryptly unpack diagnostic/build-f8536a91.logd --password 72ac58222d618b5b917b",
+ "total_modules": 10,
+ "passed": 9,
+ "failed": 1,
+ "modules": [
+ {
+ "name": "backend",
+ "status": "PASS",
+ "elapsed_seconds": 70.489,
+ "artifact": "/tmp/repos/Kickama/backend/target",
+ "output": "\u001b[1m\u001b[92m Compiling\u001b[0m proc-macro2 v1.0.106\n\u001b[1m\u001b[92m Compiling\u001b[0m unicode-ident v1.0.24\n\u001b[1m\u001b[92m Compiling\u001b[0m quote v1.0.45\n\u001b[1m\u001b[92m Compiling\u001b[0m libc v0.2.186\n\u001b[1m\u001b[92m Compiling\u001b[0m cfg-if v1.0.4\n\u001b[1m\u001b[92m Compiling\u001b[0m smallvec v1.15.2\n\u001b[1m\u001b[92m Compiling\u001b[0m pin-project-lite v0.2.17\n\u001b[1m\u001b[92m Compiling\u001b[0m stable_deref_trait v1.2.1\n\u001b[1m\u001b[92m Compiling\u001b[0m parking_lot_core v0.9.12\n\u001b[1m\u001b[92m Compiling\u001b[0m serde_core v1.0.228\n\u001b[1m\u001b[92m Compiling\u001b[0m futures-core v0.3.32\n\u001b[1m\u001b[92m Compiling\u001b[0m memchr v2.8.2\n\u001b[1m\u001b[92m Compiling\u001b[0m scopeguard v1.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m bytes v1.11.1\n\u001b[1m\u001b[92m Compiling\u001b[0m syn v2.0.117\n\u001b[1m\u001b[92m Compiling\u001b[0m lock_api v0.4.14\n\u001b[1m\u001b[92m Compiling\u001b[0m futures-sink v0.3.32\n\u001b[1m\u001b[92m Compiling\u001b[0m itoa v1.0.18\n\u001b[1m\u001b[92m Compiling\u001b[0m errno v0.3.14\n\u001b[1m\u001b[92m Compiling\u001b[0m shlex v2.0.1\n\u001b[1m\u001b[92m Compiling\u001b[0m serde v1.0.228\n\u001b[1m\u001b[92m Compiling\u001b[0m find-msvc-tools v0.1.9\n\u001b[1m\u001b[92m Compiling\u001b[0m once_cell v1.21.4\n\u001b[1m\u001b[92m Compiling\u001b[0m cc v1.2.64\n\u001b[1m\u001b[92m Compiling\u001b[0m signal-hook-registry v1.4.8\n\u001b[1m\u001b[92m Compiling\u001b[0m parking_lot v0.12.5\n\u001b[1m\u001b[92m Compiling\u001b[0m mio v1.2.1\n\u001b[1m\u001b[92m Compiling\u001b[0m socket2 v0.6.4\n\u001b[1m\u001b[92m Compiling\u001b[0m slab v0.4.12\n\u001b[1m\u001b[92m Compiling\u001b[0m pkg-config v0.3.33\n\u001b[1m\u001b[92m Compiling\u001b[0m vcpkg v0.2.15\n\u001b[1m\u001b[92m Compiling\u001b[0m tracing-core v0.1.36\n\u001b[1m\u001b[92m Compiling\u001b[0m futures-channel v0.3.32\n\u001b[1m\u001b[92m Compiling\u001b[0m writeable v0.6.3\n\u001b[1m\u001b[92m Compiling\u001b[0m openssl-sys v0.9.117\n\u001b[1m\u001b[92m Compiling\u001b[0m litemap v0.8.2\n\u001b[1m\u001b[92m Compiling\u001b[0m http v1.4.2\n\u001b[1m\u001b[92m Compiling\u001b[0m icu_properties_data v2.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m futures-io v0.3.32\n\u001b[1m\u001b[92m Compiling\u001b[0m futures-task v0.3.32\n\u001b[1m\u001b[92m Compiling\u001b[0m synstructure v0.13.2\n\u001b[1m\u001b[92m Compiling\u001b[0m utf8_iter v1.0.4\n\u001b[1m\u001b[92m Compiling\u001b[0m hashbrown v0.17.1\n\u001b[1m\u001b[92m Compiling\u001b[0m equivalent v1.0.2\n\u001b[1m\u001b[92m Compiling\u001b[0m icu_normalizer_data v2.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m indexmap v2.14.0\n\u001b[1m\u001b[92m Compiling\u001b[0m percent-encoding v2.3.2\n\u001b[1m\u001b[92m Compiling\u001b[0m version_check v0.9.5\n\u001b[1m\u001b[92m Compiling\u001b[0m http-body v1.0.1\n\u001b[1m\u001b[92m Compiling\u001b[0m generic-array v0.14.7\n\u001b[1m\u001b[92m Compiling\u001b[0m log v0.4.32\n\u001b[1m\u001b[92m Compiling\u001b[0m httparse v1.10.1\n\u001b[1m\u001b[92m Compiling\u001b[0m openssl v0.10.81\n\u001b[1m\u001b[92m Compiling\u001b[0m bitflags v2.13.0\n\u001b[1m\u001b[92m Compiling\u001b[0m foreign-types-shared v0.1.1\n\u001b[1m\u001b[92m Compiling\u001b[0m foreign-types v0.3.2\n\u001b[1m\u001b[92m Compiling\u001b[0m atomic-waker v1.1.2\n\u001b[1m\u001b[92m Compiling\u001b[0m zmij v1.0.21\n\u001b[1m\u001b[92m Compiling\u001b[0m native-tls v0.2.18\n\u001b[1m\u001b[92m Compiling\u001b[0m try-lock v0.2.5\n\u001b[1m\u001b[92m Compiling\u001b[0m tower-service v0.3.3\n\u001b[1m\u001b[92m Compiling\u001b[0m fnv v1.0.7\n\u001b[1m\u001b[92m Compiling\u001b[0m typenum v1.20.1\n\u001b[1m\u001b[92m Compiling\u001b[0m want v0.3.1\n\u001b[1m\u001b[92m Compiling\u001b[0m form_urlencoded v1.2.2\n\u001b[1m\u001b[92m Compiling\u001b[0m aho-corasick v1.1.4\n\u001b[1m\u001b[92m Compiling\u001b[0m zerofrom-derive v0.1.7\n\u001b[1m\u001b[92m Compiling\u001b[0m yoke-derive v0.8.2\n\u001b[1m\u001b[92m Compiling\u001b[0m zerovec-derive v0.11.3\n\u001b[1m\u001b[92m Compiling\u001b[0m zerofrom v0.1.8\n\u001b[1m\u001b[92m Compiling\u001b[0m displaydoc v0.2.6\n\u001b[1m\u001b[92m Compiling\u001b[0m yoke v0.8.3\n\u001b[1m\u001b[92m Compiling\u001b[0m tokio-macros v2.7.0\n\u001b[1m\u001b[92m Compiling\u001b[0m zerovec v0.11.6\n\u001b[1m\u001b[92m Compiling\u001b[0m serde_derive v1.0.228\n\u001b[1m\u001b[92m Compiling\u001b[0m tokio v1.52.3\n\u001b[1m\u001b[92m Compiling\u001b[0m tinystr v0.8.3\n\u001b[1m\u001b[92m Compiling\u001b[0m icu_locale_core v2.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m potential_utf v0.1.5\n\u001b[1m\u001b[92m Compiling\u001b[0m zerotrie v0.2.4\n\u001b[1m\u001b[92m Compiling\u001b[0m futures-macro v0.3.32\n\u001b[1m\u001b[92m Compiling\u001b[0m futures-util v0.3.32\n\u001b[1m\u001b[92m Compiling\u001b[0m icu_provider v2.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m icu_collections v2.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m tracing-attributes v0.1.31\n\u001b[1m\u001b[92m Compiling\u001b[0m icu_properties v2.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m tracing v0.1.44\n\u001b[1m\u001b[92m Compiling\u001b[0m icu_normalizer v2.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m tokio-util v0.7.18\n\u001b[1m\u001b[92m Compiling\u001b[0m openssl-macros v0.1.1\n\u001b[1m\u001b[92m Compiling\u001b[0m h2 v0.4.14\n\u001b[1m\u001b[92m Compiling\u001b[0m idna_adapter v1.2.2\n\u001b[1m\u001b[92m Compiling\u001b[0m autocfg v1.5.1\n\u001b[1m\u001b[92m Compiling\u001b[0m serde_json v1.0.150\n\u001b[1m\u001b[92m Compiling\u001b[0m regex-syntax v0.8.11\n\u001b[1m\u001b[92m Compiling\u001b[0m openssl-probe v0.2.1\n\u001b[1m\u001b[92m Compiling\u001b[0m utf8parse v0.2.2\n\u001b[1m\u001b[92m Compiling\u001b[0m anstyle-parse v1.0.0\n\u001b[1m\u001b[92m Compiling\u001b[0m regex-automata v0.4.14\n\u001b[1m\u001b[92m Compiling\u001b[0m hyper v1.10.1\n\u001b[1m\u001b[92m Compiling\u001b[0m num-traits v0.2.19\n\u001b[1m\u001b[92m Compiling\u001b[0m idna v1.1.0\n\u001b[1m\u001b[92m Compiling\u001b[0m sync_wrapper v1.0.2\n\u001b[1m\u001b[92m Compiling\u001b[0m anstyle v1.0.14\n\u001b[1m\u001b[92m Compiling\u001b[0m colorchoice v1.0.5\n\u001b[1m\u001b[92m Compiling\u001b[0m anstyle-query v1.1.5\n\u001b[1m\u001b[92m Compiling\u001b[0m crossbeam-utils v0.8.21\n\u001b[1m\u001b[92m Compiling\u001b[0m base64 v0.22.1\n\u001b[1m\u001b[92m Compiling\u001b[0m is_terminal_polyfill v1.70.2\n\u001b[1m\u001b[92m Compiling\u001b[0m ipnet v2.12.0\n\u001b[1m\u001b[92m Compiling\u001b[0m tower-layer v0.3.3\n\u001b[1m\u001b[92m Compiling\u001b[0m getrandom v0.4.2\n\u001b[1m\u001b[92m Compiling\u001b[0m tower v0.5.3\n\u001b[1m\u001b[92m Compiling\u001b[0m hyper-util v0.1.20\n\u001b[1m\u001b[92m Compiling\u001b[0m anstream v1.0.0\n\u001b[1m\u001b[92m Compiling\u001b[0m url v2.5.8\n\u001b[1m\u001b[92m Compiling\u001b[0m tokio-native-tls v0.3.1\n\u001b[1m\u001b[92m Compiling\u001b[0m crypto-common v0.1.7\n\u001b[1m\u001b[92m Compiling\u001b[0m block-buffer v0.10.4\n\u001b[1m\u001b[92m Compiling\u001b[0m toml_datetime v0.6.11\n\u001b[1m\u001b[92m Compiling\u001b[0m serde_spanned v0.6.9\n\u001b[1m\u001b[92m Compiling\u001b[0m http-body-util v0.1.3\n\u001b[1m\u001b[92m Compiling\u001b[0m winnow v0.7.15\n\u001b[1m\u001b[92m Compiling\u001b[0m lazy_static v1.5.0\n\u001b[1m\u001b[92m Compiling\u001b[0m toml_write v0.1.2\n\u001b[1m\u001b[92m Compiling\u001b[0m anyhow v1.0.102\n\u001b[1m\u001b[92m Compiling\u001b[0m clap_lex v1.1.0\n\u001b[1m\u001b[92m Compiling\u001b[0m heck v0.5.0\n\u001b[1m\u001b[92m Compiling\u001b[0m zeroize v1.9.0\n\u001b[1m\u001b[92m Compiling\u001b[0m ryu v1.0.23\n\u001b[1m\u001b[92m Compiling\u001b[0m strsim v0.11.1\n\u001b[1m\u001b[92m Compiling\u001b[0m thiserror v2.0.18\n\u001b[1m\u001b[92m Compiling\u001b[0m clap_builder v4.6.0\n\u001b[1m\u001b[92m Compiling\u001b[0m serde_urlencoded v0.7.1\n\u001b[1m\u001b[92m Compiling\u001b[0m rustls-pki-types v1.14.1\n\u001b[1m\u001b[92m Compiling\u001b[0m clap_derive v4.6.1\n\u001b[1m\u001b[92m Compiling\u001b[0m toml_edit v0.22.27\n\u001b[1m\u001b[92m Compiling\u001b[0m hyper-tls v0.6.0\n\u001b[1m\u001b[92m Compiling\u001b[0m sharded-slab v0.1.7\n\u001b[1m\u001b[92m Compiling\u001b[0m digest v0.10.7\n\u001b[1m\u001b[92m Compiling\u001b[0m tower-http v0.6.11\n\u001b[1m\u001b[92m Compiling\u001b[0m matchers v0.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m futures-executor v0.3.32\n\u001b[1m\u001b[92m Compiling\u001b[0m tracing-serde v0.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m thiserror-impl v2.0.18\n\u001b[1m\u001b[92m Compiling\u001b[0m tracing-log v0.2.0\n\u001b[1m\u001b[92m Compiling\u001b[0m thread_local v1.1.9\n\u001b[1m\u001b[92m Compiling\u001b[0m encoding_rs v0.8.35\n\u001b[1m\u001b[92m Compiling\u001b[0m nu-ansi-term v0.50.3\n\u001b[1m\u001b[92m Compiling\u001b[0m iana-time-zone v0.1.65\n\u001b[1m\u001b[92m Compiling\u001b[0m cpufeatures v0.2.17\n\u001b[1m\u001b[92m Compiling\u001b[0m hashbrown v0.14.5\n\u001b[1m\u001b[92m Compiling\u001b[0m mime v0.3.17\n\u001b[1m\u001b[92m Compiling\u001b[0m reqwest v0.12.28\n\u001b[1m\u001b[92m Compiling\u001b[0m sha2 v0.10.9\n\u001b[1m\u001b[92m Compiling\u001b[0m dashmap v6.2.1\n\u001b[1m\u001b[92m Compiling\u001b[0m chrono v0.4.45\n\u001b[1m\u001b[92m Compiling\u001b[0m tracing-subscriber v0.3.23\n\u001b[1m\u001b[92m Compiling\u001b[0m futures v0.3.32\n\u001b[1m\u001b[92m Compiling\u001b[0m uuid v1.23.3\n\u001b[1m\u001b[92m Compiling\u001b[0m toml v0.8.23\n\u001b[1m\u001b[92m Compiling\u001b[0m clap v4.6.1\n\u001b[1m\u001b[92m Compiling\u001b[0m regex v1.12.4\n\u001b[1m\u001b[92m Compiling\u001b[0m async-trait v0.1.89\n\u001b[1m\u001b[92m Compiling\u001b[0m tent-backend v0.1.0 (/tmp/repos/Kickama/backend)\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `warn`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/embeddings.rs:28:28\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m28\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use tracing::{debug, info, warn};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(unused_imports)]` (part of `#[warn(unused)]`) on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `error`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:25:22\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m25\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use tracing::{debug, error, info, warn};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `error` and `warn`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/mod.rs:40:22\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m40\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use tracing::{debug, error, info, warn};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `c_int` and `c_uint`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:38:20\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m38\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::os::raw::{c_int, c_uint, c_ulong};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `std::ffi::CString`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/legacy.rs:35:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m35\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::ffi::CString;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `c_char`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/legacy.rs:36:20\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m36\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::os::raw::{c_char, c_ulong};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `CStr`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/types.rs:27:16\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m27\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::ffi::{CStr, CString};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `c_double` and `c_long`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/types.rs:29:28\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m29\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::os::raw::{c_char, c_double, c_int, c_uint, c_void, c_long, c_ulong};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `AtomicBool`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:14:25\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m14\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `EntityKind` and `legacy_normalize_phone_number`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/v1_compat.rs:8:47\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m8\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use crate::legacy::deprecations::{LegacyUuid, EntityKind, LegacyPagination, legacy_normalize_phone_number};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `super::ProtocolError`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/validate.rs:27:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m27\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use super::ProtocolError;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `MAX_MESSAGE_SIZE`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/codec.rs:25:38\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m25\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use crate::protocol::{ProtocolError, MAX_MESSAGE_SIZE, MIN_COMPATIBLE_VERSION, PROTOCOL_VERSION};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `Write`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/codec.rs:26:29\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m26\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::io::{Cursor, Read, Write};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `Ordering`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:25:36\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m25\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::sync::atomic::{AtomicU64, Ordering};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `Duration` and `Instant`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:27:17\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m27\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::time::{Duration, Instant};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `Deserialize` and `Serialize`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:28:13\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m28\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use serde::{Deserialize, Serialize};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `MAX_MESSAGE_SIZE`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:31:28\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m31\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use super::{ProtocolError, MAX_MESSAGE_SIZE, DEFAULT_TIMEOUT_MS};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `FrameDecoder` and `FrameEncoder`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:32:27\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m32\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use super::codec::{Frame, FrameEncoder, FrameDecoder, FLAG_REQUIRES_ACK};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: use of deprecated unit variant `legacy::deprecations::EntityKind::Team`: Teams are now Organizations. Use Organization instead.\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:244:25\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m244\u001b[0m \u001b[1m\u001b[94m|\u001b[0m EntityKind::Team => \"org\", // Legacy mapping\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(deprecated)]` on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: use of deprecated unit variant `legacy::deprecations::EntityKind::Project`: Projects were removed in the Platform v2 migration\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:245:25\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m245\u001b[0m \u001b[1m\u001b[94m|\u001b[0m EntityKind::Project => \"workspace\", // Legacy mapping\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: use of deprecated unit variant `legacy::deprecations::EntityKind::Team`: Teams are now Organizations. Use Organization instead.\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:266:25\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m266\u001b[0m \u001b[1m\u001b[94m|\u001b[0m EntityKind::Team\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: use of deprecated unit variant `legacy::deprecations::EntityKind::Project`: Projects were removed in the Platform v2 migration\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:267:31\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m267\u001b[0m \u001b[1m\u001b[94m|\u001b[0m | EntityKind::Project\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: variable does not need to be mutable\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:317:13\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m317\u001b[0m \u001b[1m\u001b[94m|\u001b[0m let mut buffer = unsafe { &mut *c_buffer };\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m----\u001b[0m\u001b[1m\u001b[33m^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94mhelp: remove this `mut`\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(unused_mut)]` (part of `#[warn(unused)]`) on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused variable: `initialized`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:440:13\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m440\u001b[0m \u001b[1m\u001b[94m|\u001b[0m let initialized = Arc::new(AtomicBool::new(true));\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33mhelp: if this is intentional, prefix it with an underscore: `_initialized`\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(unused_variables)]` (part of `#[warn(unused)]`) on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: variable does not need to be mutable\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/legacy.rs:267:13\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m267\u001b[0m \u001b[1m\u001b[94m|\u001b[0m let mut buffer = unsafe { &mut *c_buffer };\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m----\u001b[0m\u001b[1m\u001b[33m^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94mhelp: remove this `mut`\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused variable: `value`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:508:15\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m508\u001b[0m \u001b[1m\u001b[94m|\u001b[0m for (key, value) in configs {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m \u001b[1m\u001b[33mhelp: if this is intentional, prefix it with an underscore: `_value`\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused variable: `obj`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/validate.rs:282:25\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m282\u001b[0m \u001b[1m\u001b[94m|\u001b[0m if let Some(obj) = value.as_object() {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^\u001b[0m \u001b[1m\u001b[33mhelp: if this is intentional, prefix it with an underscore: `_obj`\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: type `BridgeStats` is more private than the item `ConnectorBridge::stats`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:415:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m415\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub fn stats(&self) -> BridgeStats {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33mmethod `ConnectorBridge::stats` is reachable at visibility `pub`\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[92mnote\u001b[0m: but type `BridgeStats` is only usable at visibility `pub(self)`\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:225:1\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m225\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct BridgeStats {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[92m^^^^^^^^^^^^^^^^^^\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(private_interfaces)]` on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: type `CircuitState` is more private than the item `ConnectorBridge::circuit_state`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:423:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m423\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub fn circuit_state(&self) -> CircuitState {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33mmethod `ConnectorBridge::circuit_state` is reachable at visibility `pub`\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[92mnote\u001b[0m: but type `CircuitState` is only usable at visibility `pub(self)`\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:79:1\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m 79\u001b[0m \u001b[1m\u001b[94m|\u001b[0m enum CircuitState {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[92m^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `NCP_TEMPERATURE` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/mod.rs:53:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m53\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const NCP_TEMPERATURE: f64 = 0.42;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `MIN_CONFIDENCE_THRESHOLD` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/mod.rs:61:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m61\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const MIN_CONFIDENCE_THRESHOLD: f64 = 0.65;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `MAX_INFERENCE_RETRIES` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/mod.rs:65:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m65\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const MAX_INFERENCE_RETRIES: u32 = 5;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: fields `discovery`, `broker`, and `registry` are never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/mod.rs:173:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m171\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct AiOrchestrator {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m--------------\u001b[0m \u001b[1m\u001b[94mfields in this struct\u001b[0m\n\u001b[1m\u001b[94m172\u001b[0m \u001b[1m\u001b[94m|\u001b[0m /// Reference to the service discovery subsystem\n\u001b[1m\u001b[94m173\u001b[0m \u001b[1m\u001b[94m|\u001b[0m discovery: Arc>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m174\u001b[0m \u001b[1m\u001b[94m|\u001b[0m /// Reference to the message broker subsystem\n\u001b[1m\u001b[94m175\u001b[0m \u001b[1m\u001b[94m|\u001b[0m broker: Arc>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\u001b[1m\u001b[94m176\u001b[0m \u001b[1m\u001b[94m|\u001b[0m /// Reference to the service registry subsystem\n\u001b[1m\u001b[94m177\u001b[0m \u001b[1m\u001b[94m|\u001b[0m registry: Arc>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `window_start` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/embeddings.rs:661:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m658\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct ContextWindowManager {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m--------------------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m661\u001b[0m \u001b[1m\u001b[94m|\u001b[0m window_start: Instant,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `MAX_RETRIES` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:41:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m41\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const MAX_RETRIES: u32 = 3;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `RETRY_BASE_DELAY_MS` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:44:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m44\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const RETRY_BASE_DELAY_MS: u64 = 1000;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: fields `api_key`, `base_url`, and `client` are never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:453:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m452\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct AnthropicClient {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------------\u001b[0m \u001b[1m\u001b[94mfields in this struct\u001b[0m\n\u001b[1m\u001b[94m453\u001b[0m \u001b[1m\u001b[94m|\u001b[0m api_key: String,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m454\u001b[0m \u001b[1m\u001b[94m|\u001b[0m base_url: String,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m455\u001b[0m \u001b[1m\u001b[94m|\u001b[0m models: Vec,\n\u001b[1m\u001b[94m456\u001b[0m \u001b[1m\u001b[94m|\u001b[0m client: reqwest::Client,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `AnthropicClient` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `routing_table` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:719:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m716\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct ModelRouter {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m-----------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m719\u001b[0m \u001b[1m\u001b[94m|\u001b[0m routing_table: RwLock>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `ModelRouter` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `cost_history` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:951:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m947\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct TokenCounter {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m------------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m951\u001b[0m \u001b[1m\u001b[94m|\u001b[0m cost_history: RwLock>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `HEALTH_CHECK_TIMEOUT_MS` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:64:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m64\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const HEALTH_CHECK_TIMEOUT_MS: u64 = 1000;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `id` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:152:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m151\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct PoolEntry {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m152\u001b[0m \u001b[1m\u001b[94m|\u001b[0m id: usize,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: method `stats` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:195:8\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m163\u001b[0m \u001b[1m\u001b[94m|\u001b[0m impl ConnectionPool {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m-------------------\u001b[0m \u001b[1m\u001b[94mmethod in this implementation\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m195\u001b[0m \u001b[1m\u001b[94m|\u001b[0m fn stats(&self) -> PoolStats {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: struct `PoolStats` is never constructed\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:203:8\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m203\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct PoolStats {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: fields `circuit_breaker_trips` and `health_check_failures` are never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:229:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m225\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct BridgeStats {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m-----------\u001b[0m \u001b[1m\u001b[94mfields in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m229\u001b[0m \u001b[1m\u001b[94m|\u001b[0m circuit_breaker_trips: u64,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m230\u001b[0m \u001b[1m\u001b[94m|\u001b[0m health_check_failures: u64,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `BridgeStats` has derived impls for the traits `Clone` and `Debug`, but these are intentionally ignored during dead code analysis\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `consumers` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/messaging/mod.rs:38:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m35\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct MessageBroker {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m-------------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m38\u001b[0m \u001b[1m\u001b[94m|\u001b[0m consumers: DashMap>>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `version` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/messages.rs:293:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m291\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct MessageRegistry {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m292\u001b[0m \u001b[1m\u001b[94m|\u001b[0m handlers: HashMap,\n\u001b[1m\u001b[94m293\u001b[0m \u001b[1m\u001b[94m|\u001b[0m version: u32,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `version` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/serialize.rs:258:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m255\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct Schema {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m258\u001b[0m \u001b[1m\u001b[94m|\u001b[0m version: u32,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: fields `required` and `default_value` are never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/serialize.rs:264:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m261\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct SchemaField {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m-----------\u001b[0m \u001b[1m\u001b[94mfields in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m264\u001b[0m \u001b[1m\u001b[94m|\u001b[0m required: bool,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m265\u001b[0m \u001b[1m\u001b[94m|\u001b[0m default_value: Option,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: variant `Custom` is never constructed\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/serialize.rs:276:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m269\u001b[0m \u001b[1m\u001b[94m|\u001b[0m enum FieldValidation {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------------\u001b[0m \u001b[1m\u001b[94mvariant in this enum\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m276\u001b[0m \u001b[1m\u001b[94m|\u001b[0m Custom(String),\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: fields `next_request_id`, `pending_requests`, `serializer`, and `timeout_ms` are never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:218:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m217\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct RpcClient {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------\u001b[0m \u001b[1m\u001b[94mfields in this struct\u001b[0m\n\u001b[1m\u001b[94m218\u001b[0m \u001b[1m\u001b[94m|\u001b[0m next_request_id: AtomicU64,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m219\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pending_requests: Arc, RpcError>>>>>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m220\u001b[0m \u001b[1m\u001b[94m|\u001b[0m serializer: Serializer,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m221\u001b[0m \u001b[1m\u001b[94m|\u001b[0m timeout_ms: u64,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `serializer` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:271:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m269\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct RpcServer {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m270\u001b[0m \u001b[1m\u001b[94m|\u001b[0m handlers: HashMap,\n\u001b[1m\u001b[94m271\u001b[0m \u001b[1m\u001b[94m|\u001b[0m serializer: Serializer,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `events` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/registry/mod.rs:31:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m28\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct ServiceRegistry {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m31\u001b[0m \u001b[1m\u001b[94m|\u001b[0m events: Arc>>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m: `tent-backend` (lib) generated 52 warnings (run `cargo fix --lib -p tent-backend` to apply 23 suggestions)\n\u001b[1m\u001b[92m Finished\u001b[0m `dev` profile [unoptimized + debuginfo] target(s) in 1m 10s"
+ },
+ {
+ "name": "frontend",
+ "status": "PASS",
+ "elapsed_seconds": 7.374,
+ "artifact": "/tmp/repos/Kickama/frontend/dist",
+ "output": "> tent-frontend@0.0.0 build\n> tsc -b && vite build\n\nvite v6.4.3 building for production...\ntransforming...\n\u2713 100 modules transformed.\nrendering chunks...\ncomputing gzip size...\ndist/index.html 0.62 kB \u2502 gzip: 0.34 kB\ndist/assets/state-BkjSKDbY.js 8.91 kB \u2502 gzip: 3.54 kB \u2502 map: 57.15 kB\ndist/assets/vendor-CREcWLHI.js 48.93 kB \u2502 gzip: 17.25 kB \u2502 map: 481.27 kB\ndist/assets/index-CyxcoTyU.js 231.32 kB \u2502 gzip: 72.16 kB \u2502 map: 1,044.42 kB\n\u2713 built in 2.34s"
+ },
+ {
+ "name": "market",
+ "status": "PASS",
+ "elapsed_seconds": 0.799,
+ "artifact": "/tmp/repos/Kickama/market/market",
+ "output": ""
+ },
+ {
+ "name": "frailbox",
+ "status": "PASS",
+ "elapsed_seconds": 0.003,
+ "artifact": "/tmp/repos/Kickama/frailbox/frailbox",
+ "output": "make: Nothing to be done for 'all'."
+ },
+ {
+ "name": "engine",
+ "status": "PASS",
+ "elapsed_seconds": 0.117,
+ "artifact": "/tmp/repos/Kickama/frailbox/engine/build/trial-engine",
+ "output": "[100%] Built target trial-engine"
+ },
+ {
+ "name": "compliance",
+ "status": "PASS",
+ "elapsed_seconds": 1.313,
+ "artifact": "/tmp/repos/Kickama/compliance/build",
+ "output": "Note: ComplianceAuditor.java uses or overrides a deprecated API.\nNote: Recompile with -Xlint:deprecation for details."
+ },
+ {
+ "name": "v2-market-stream",
+ "status": "PASS",
+ "elapsed_seconds": 0.016,
+ "artifact": null,
+ "output": "Syntax OK"
+ },
+ {
+ "name": "nfc-scanner",
+ "status": "PASS",
+ "elapsed_seconds": 0.002,
+ "artifact": null,
+ "output": ""
+ },
+ {
+ "name": "openapi-haskell",
+ "status": "FAIL",
+ "elapsed_seconds": 0.367,
+ "artifact": null,
+ "output": "[1 of 8] Compiling Network.HTTP.Types ( Network/HTTP/Types.hs, nothing )\n[2 of 8] Compiling Network.Wai ( Network/Wai.hs, nothing )\n[3 of 8] Compiling Network.Wai.Handler.Warp ( Network/Wai/Handler/Warp.hs, nothing )\n[4 of 8] Compiling Network.Wai.Logger ( Network/Wai/Logger.hs, nothing )\n[5 of 8] Compiling Tent.OpenAPI.Types ( Types.hs, /tmp/ghc49074_0/ghc_4.o, /tmp/ghc49074_0/ghc_4.dyn_o )\nTypes.hs:50:1: error: [GHC-61948]\n Could not find module \u2018Data.Aeson\u2019.\n Perhaps you meant Data.Version (from base-4.20.2.0)\n Use -v to see a list of the files searched for.\n |\n50 | import Data.Aeson (FromJSON(parseJSON), ToJSON(toJSON), Value(Object), (.!=), (.:?), (.=))\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:51:1: error: [GHC-87110]\n Could not find module \u2018Data.Aeson.Types\u2019.\n Use -v to see a list of the files searched for.\n |\n51 | import Data.Aeson.Types (Parser, parseMaybe)\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:71:1: error: [GHC-61948]\n Could not find module \u2018Data.Aeson\u2019.\n Perhaps you meant Data.Version (from base-4.20.2.0)\n Use -v to see a list of the files searched for.\n |\n71 | import qualified Data.Aeson as A\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:72:1: error: [GHC-87110]\n Could not find module \u2018Data.Aeson.Key\u2019.\n Use -v to see a list of the files searched for.\n |\n72 | import qualified Data.Aeson.Key as K\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:73:1: error: [GHC-87110]\n Could not find module \u2018Data.Aeson.KeyMap\u2019.\n Use -v to see a list of the files searched for.\n |\n73 | import qualified Data.Aeson.KeyMap as KM\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:74:1: error: [GHC-61948]\n Could not find module \u2018Data.HashMap.Strict\u2019.\n Perhaps you meant\n Data.Map.Strict (from containers-0.7)\n Data.IntMap.Strict (from containers-0.7)\n Use -v to see a list of the files searched for.\n |\n74 | import qualified Data.HashMap.Strict as HM\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:77:1: error: [GHC-87110]\n Could not find module \u2018Data.Yaml\u2019.\n Use -v to see a list of the files searched for.\n |\n77 | import qualified Data.Yaml as Y\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
+ },
+ {
+ "name": "openapi-tools",
+ "status": "PASS",
+ "elapsed_seconds": 0.004,
+ "artifact": null,
+ "output": ""
+ }
+ ],
+ "pr_note": "Include the encrypted diagnostic logd artifact(s): diagnostic/build-f8536a91.logd. The encrypted .logd is the required diagnostic content for PR review; this JSON file is metadata. Maintainers may ask you to remove these diagnostic artifacts before merging."
+}
diff --git a/diagnostic/build-f8536a91.logd b/diagnostic/build-f8536a91.logd
new file mode 100644
index 00000000..11e38b03
Binary files /dev/null and b/diagnostic/build-f8536a91.logd differ
diff --git a/diagnostic/build-fc2f2c0f.json b/diagnostic/build-fc2f2c0f.json
new file mode 100644
index 00000000..40ce5570
--- /dev/null
+++ b/diagnostic/build-fc2f2c0f.json
@@ -0,0 +1,87 @@
+{
+ "generated_at": "2026-06-19T05:58:07.046812+00:00",
+ "commit": "fc2f2c0f",
+ "diagnostic_logd": "diagnostic/build-fc2f2c0f.logd",
+ "diagnostic_logd_error": null,
+ "message_blocker": null,
+ "chunked": false,
+ "chunk_size_bytes": null,
+ "password": "6e04e95c2ea7cdbd474c",
+ "decrypt_command": "encryptly unpack diagnostic/build-fc2f2c0f.logd --password 6e04e95c2ea7cdbd474c",
+ "total_modules": 10,
+ "passed": 7,
+ "failed": 3,
+ "modules": [
+ {
+ "name": "backend",
+ "status": "PASS",
+ "elapsed_seconds": 0.451,
+ "artifact": "/tmp/repos/Kickama/backend/target",
+ "output": "\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `warn`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/embeddings.rs:28:28\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m28\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use tracing::{debug, info, warn};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(unused_imports)]` (part of `#[warn(unused)]`) on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `error`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:25:22\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m25\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use tracing::{debug, error, info, warn};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `error` and `warn`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/mod.rs:40:22\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m40\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use tracing::{debug, error, info, warn};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `c_int` and `c_uint`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:38:20\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m38\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::os::raw::{c_int, c_uint, c_ulong};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `std::ffi::CString`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/legacy.rs:35:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m35\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::ffi::CString;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `c_char`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/legacy.rs:36:20\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m36\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::os::raw::{c_char, c_ulong};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `CStr`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/types.rs:27:16\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m27\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::ffi::{CStr, CString};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `c_double` and `c_long`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/types.rs:29:28\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m29\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::os::raw::{c_char, c_double, c_int, c_uint, c_void, c_long, c_ulong};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `AtomicBool`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:14:25\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m14\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `EntityKind` and `legacy_normalize_phone_number`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/v1_compat.rs:8:47\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m8\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use crate::legacy::deprecations::{LegacyUuid, EntityKind, LegacyPagination, legacy_normalize_phone_number};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `super::ProtocolError`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/validate.rs:27:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m27\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use super::ProtocolError;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `MAX_MESSAGE_SIZE`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/codec.rs:25:38\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m25\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use crate::protocol::{ProtocolError, MAX_MESSAGE_SIZE, MIN_COMPATIBLE_VERSION, PROTOCOL_VERSION};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `Write`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/codec.rs:26:29\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m26\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::io::{Cursor, Read, Write};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `Ordering`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:25:36\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m25\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::sync::atomic::{AtomicU64, Ordering};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `Duration` and `Instant`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:27:17\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m27\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::time::{Duration, Instant};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `Deserialize` and `Serialize`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:28:13\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m28\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use serde::{Deserialize, Serialize};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `MAX_MESSAGE_SIZE`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:31:28\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m31\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use super::{ProtocolError, MAX_MESSAGE_SIZE, DEFAULT_TIMEOUT_MS};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused imports: `FrameDecoder` and `FrameEncoder`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:32:27\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m32\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use super::codec::{Frame, FrameEncoder, FrameDecoder, FLAG_REQUIRES_ACK};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: use of deprecated unit variant `legacy::deprecations::EntityKind::Team`: Teams are now Organizations. Use Organization instead.\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:244:25\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m244\u001b[0m \u001b[1m\u001b[94m|\u001b[0m EntityKind::Team => \"org\", // Legacy mapping\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(deprecated)]` on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: use of deprecated unit variant `legacy::deprecations::EntityKind::Project`: Projects were removed in the Platform v2 migration\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:245:25\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m245\u001b[0m \u001b[1m\u001b[94m|\u001b[0m EntityKind::Project => \"workspace\", // Legacy mapping\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: use of deprecated unit variant `legacy::deprecations::EntityKind::Team`: Teams are now Organizations. Use Organization instead.\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:266:25\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m266\u001b[0m \u001b[1m\u001b[94m|\u001b[0m EntityKind::Team\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: use of deprecated unit variant `legacy::deprecations::EntityKind::Project`: Projects were removed in the Platform v2 migration\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:267:31\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m267\u001b[0m \u001b[1m\u001b[94m|\u001b[0m | EntityKind::Project\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: variable does not need to be mutable\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:317:13\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m317\u001b[0m \u001b[1m\u001b[94m|\u001b[0m let mut buffer = unsafe { &mut *c_buffer };\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m----\u001b[0m\u001b[1m\u001b[33m^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94mhelp: remove this `mut`\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(unused_mut)]` (part of `#[warn(unused)]`) on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused variable: `initialized`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:440:13\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m440\u001b[0m \u001b[1m\u001b[94m|\u001b[0m let initialized = Arc::new(AtomicBool::new(true));\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33mhelp: if this is intentional, prefix it with an underscore: `_initialized`\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(unused_variables)]` (part of `#[warn(unused)]`) on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: variable does not need to be mutable\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/legacy.rs:267:13\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m267\u001b[0m \u001b[1m\u001b[94m|\u001b[0m let mut buffer = unsafe { &mut *c_buffer };\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m----\u001b[0m\u001b[1m\u001b[33m^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94mhelp: remove this `mut`\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused variable: `value`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/legacy/deprecations.rs:508:15\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m508\u001b[0m \u001b[1m\u001b[94m|\u001b[0m for (key, value) in configs {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m \u001b[1m\u001b[33mhelp: if this is intentional, prefix it with an underscore: `_value`\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused variable: `obj`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/validate.rs:282:25\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m282\u001b[0m \u001b[1m\u001b[94m|\u001b[0m if let Some(obj) = value.as_object() {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^\u001b[0m \u001b[1m\u001b[33mhelp: if this is intentional, prefix it with an underscore: `_obj`\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: type `BridgeStats` is more private than the item `ConnectorBridge::stats`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:415:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m415\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub fn stats(&self) -> BridgeStats {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33mmethod `ConnectorBridge::stats` is reachable at visibility `pub`\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[92mnote\u001b[0m: but type `BridgeStats` is only usable at visibility `pub(self)`\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:225:1\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m225\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct BridgeStats {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[92m^^^^^^^^^^^^^^^^^^\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(private_interfaces)]` on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: type `CircuitState` is more private than the item `ConnectorBridge::circuit_state`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:423:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m423\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub fn circuit_state(&self) -> CircuitState {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33mmethod `ConnectorBridge::circuit_state` is reachable at visibility `pub`\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[92mnote\u001b[0m: but type `CircuitState` is only usable at visibility `pub(self)`\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:79:1\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m 79\u001b[0m \u001b[1m\u001b[94m|\u001b[0m enum CircuitState {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[92m^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `NCP_TEMPERATURE` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/mod.rs:53:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m53\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const NCP_TEMPERATURE: f64 = 0.42;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `MIN_CONFIDENCE_THRESHOLD` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/mod.rs:61:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m61\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const MIN_CONFIDENCE_THRESHOLD: f64 = 0.65;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `MAX_INFERENCE_RETRIES` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/mod.rs:65:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m65\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const MAX_INFERENCE_RETRIES: u32 = 5;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: fields `discovery`, `broker`, and `registry` are never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/mod.rs:173:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m171\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct AiOrchestrator {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m--------------\u001b[0m \u001b[1m\u001b[94mfields in this struct\u001b[0m\n\u001b[1m\u001b[94m172\u001b[0m \u001b[1m\u001b[94m|\u001b[0m /// Reference to the service discovery subsystem\n\u001b[1m\u001b[94m173\u001b[0m \u001b[1m\u001b[94m|\u001b[0m discovery: Arc>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m174\u001b[0m \u001b[1m\u001b[94m|\u001b[0m /// Reference to the message broker subsystem\n\u001b[1m\u001b[94m175\u001b[0m \u001b[1m\u001b[94m|\u001b[0m broker: Arc>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\u001b[1m\u001b[94m176\u001b[0m \u001b[1m\u001b[94m|\u001b[0m /// Reference to the service registry subsystem\n\u001b[1m\u001b[94m177\u001b[0m \u001b[1m\u001b[94m|\u001b[0m registry: Arc>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `window_start` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/embeddings.rs:661:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m658\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct ContextWindowManager {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m--------------------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m661\u001b[0m \u001b[1m\u001b[94m|\u001b[0m window_start: Instant,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `MAX_RETRIES` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:41:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m41\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const MAX_RETRIES: u32 = 3;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `RETRY_BASE_DELAY_MS` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:44:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m44\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const RETRY_BASE_DELAY_MS: u64 = 1000;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: fields `api_key`, `base_url`, and `client` are never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:453:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m452\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct AnthropicClient {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------------\u001b[0m \u001b[1m\u001b[94mfields in this struct\u001b[0m\n\u001b[1m\u001b[94m453\u001b[0m \u001b[1m\u001b[94m|\u001b[0m api_key: String,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m454\u001b[0m \u001b[1m\u001b[94m|\u001b[0m base_url: String,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m455\u001b[0m \u001b[1m\u001b[94m|\u001b[0m models: Vec,\n\u001b[1m\u001b[94m456\u001b[0m \u001b[1m\u001b[94m|\u001b[0m client: reqwest::Client,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `AnthropicClient` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `routing_table` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:719:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m716\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct ModelRouter {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m-----------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m719\u001b[0m \u001b[1m\u001b[94m|\u001b[0m routing_table: RwLock>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `ModelRouter` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `cost_history` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/ai/inference.rs:951:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m947\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct TokenCounter {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m------------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m951\u001b[0m \u001b[1m\u001b[94m|\u001b[0m cost_history: RwLock>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: constant `HEALTH_CHECK_TIMEOUT_MS` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:64:7\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m64\u001b[0m \u001b[1m\u001b[94m|\u001b[0m const HEALTH_CHECK_TIMEOUT_MS: u64 = 1000;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `id` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:152:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m151\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct PoolEntry {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m152\u001b[0m \u001b[1m\u001b[94m|\u001b[0m id: usize,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: method `stats` is never used\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:195:8\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m163\u001b[0m \u001b[1m\u001b[94m|\u001b[0m impl ConnectionPool {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m-------------------\u001b[0m \u001b[1m\u001b[94mmethod in this implementation\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m195\u001b[0m \u001b[1m\u001b[94m|\u001b[0m fn stats(&self) -> PoolStats {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: struct `PoolStats` is never constructed\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:203:8\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m203\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct PoolStats {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: fields `circuit_breaker_trips` and `health_check_failures` are never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/connector/bridge.rs:229:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m225\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct BridgeStats {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m-----------\u001b[0m \u001b[1m\u001b[94mfields in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m229\u001b[0m \u001b[1m\u001b[94m|\u001b[0m circuit_breaker_trips: u64,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m230\u001b[0m \u001b[1m\u001b[94m|\u001b[0m health_check_failures: u64,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `BridgeStats` has derived impls for the traits `Clone` and `Debug`, but these are intentionally ignored during dead code analysis\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `consumers` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/messaging/mod.rs:38:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m35\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct MessageBroker {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m-------------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m38\u001b[0m \u001b[1m\u001b[94m|\u001b[0m consumers: DashMap>>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `version` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/messages.rs:293:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m291\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct MessageRegistry {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m292\u001b[0m \u001b[1m\u001b[94m|\u001b[0m handlers: HashMap,\n\u001b[1m\u001b[94m293\u001b[0m \u001b[1m\u001b[94m|\u001b[0m version: u32,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `version` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/serialize.rs:258:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m255\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct Schema {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m258\u001b[0m \u001b[1m\u001b[94m|\u001b[0m version: u32,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: fields `required` and `default_value` are never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/serialize.rs:264:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m261\u001b[0m \u001b[1m\u001b[94m|\u001b[0m struct SchemaField {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m-----------\u001b[0m \u001b[1m\u001b[94mfields in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m264\u001b[0m \u001b[1m\u001b[94m|\u001b[0m required: bool,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m265\u001b[0m \u001b[1m\u001b[94m|\u001b[0m default_value: Option,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: variant `Custom` is never constructed\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/serialize.rs:276:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m269\u001b[0m \u001b[1m\u001b[94m|\u001b[0m enum FieldValidation {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------------\u001b[0m \u001b[1m\u001b[94mvariant in this enum\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m276\u001b[0m \u001b[1m\u001b[94m|\u001b[0m Custom(String),\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: fields `next_request_id`, `pending_requests`, `serializer`, and `timeout_ms` are never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:218:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m217\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct RpcClient {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------\u001b[0m \u001b[1m\u001b[94mfields in this struct\u001b[0m\n\u001b[1m\u001b[94m218\u001b[0m \u001b[1m\u001b[94m|\u001b[0m next_request_id: AtomicU64,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m219\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pending_requests: Arc, RpcError>>>>>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m220\u001b[0m \u001b[1m\u001b[94m|\u001b[0m serializer: Serializer,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^\u001b[0m\n\u001b[1m\u001b[94m221\u001b[0m \u001b[1m\u001b[94m|\u001b[0m timeout_ms: u64,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `serializer` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/protocol/rpc.rs:271:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m269\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct RpcServer {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m270\u001b[0m \u001b[1m\u001b[94m|\u001b[0m handlers: HashMap,\n\u001b[1m\u001b[94m271\u001b[0m \u001b[1m\u001b[94m|\u001b[0m serializer: Serializer,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: field `events` is never read\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0msrc/registry/mod.rs:31:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m28\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub struct ServiceRegistry {\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[94m---------------\u001b[0m \u001b[1m\u001b[94mfield in this struct\u001b[0m\n\u001b[1m\u001b[94m...\u001b[0m\n\u001b[1m\u001b[94m31\u001b[0m \u001b[1m\u001b[94m|\u001b[0m events: Arc>>,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^\u001b[0m\n\n\u001b[1m\u001b[33mwarning\u001b[0m: `tent-backend` (lib) generated 52 warnings (run `cargo fix --lib -p tent-backend` to apply 23 suggestions)\n\u001b[1m\u001b[92m Finished\u001b[0m `dev` profile [unoptimized + debuginfo] target(s) in 0.39s"
+ },
+ {
+ "name": "frontend",
+ "status": "PASS",
+ "elapsed_seconds": 18.96,
+ "artifact": "/tmp/repos/Kickama/frontend/dist",
+ "output": "> tent-frontend@0.0.0 build\n> tsc -b && vite build\n\nvite v6.4.3 building for production...\ntransforming...\n\u2713 100 modules transformed.\nrendering chunks...\ncomputing gzip size...\ndist/index.html 0.62 kB \u2502 gzip: 0.34 kB\ndist/assets/state-BkjSKDbY.js 8.91 kB \u2502 gzip: 3.54 kB \u2502 map: 57.15 kB\ndist/assets/vendor-CREcWLHI.js 48.93 kB \u2502 gzip: 17.25 kB \u2502 map: 481.27 kB\ndist/assets/index-CyxcoTyU.js 231.32 kB \u2502 gzip: 72.16 kB \u2502 map: 1,044.42 kB\n\u2713 built in 6.62s"
+ },
+ {
+ "name": "market",
+ "status": "PASS",
+ "elapsed_seconds": 2.209,
+ "artifact": "/tmp/repos/Kickama/market/market",
+ "output": ""
+ },
+ {
+ "name": "frailbox",
+ "status": "PASS",
+ "elapsed_seconds": 0.007,
+ "artifact": "/tmp/repos/Kickama/frailbox/frailbox",
+ "output": "make: Nothing to be done for 'all'."
+ },
+ {
+ "name": "engine",
+ "status": "PASS",
+ "elapsed_seconds": 0.337,
+ "artifact": "/tmp/repos/Kickama/frailbox/engine/build/trial-engine",
+ "output": "[100%] Built target trial-engine"
+ },
+ {
+ "name": "compliance",
+ "status": "PASS",
+ "elapsed_seconds": 3.65,
+ "artifact": "/tmp/repos/Kickama/compliance/build",
+ "output": "Note: ComplianceAuditor.java uses or overrides a deprecated API.\nNote: Recompile with -Xlint:deprecation for details."
+ },
+ {
+ "name": "v2-market-stream",
+ "status": "PASS",
+ "elapsed_seconds": 0.037,
+ "artifact": null,
+ "output": "Syntax OK"
+ },
+ {
+ "name": "nfc-scanner",
+ "status": "FAIL",
+ "elapsed_seconds": 0,
+ "artifact": null,
+ "output": "Command not found: [Errno 2] No such file or directory: 'luac'"
+ },
+ {
+ "name": "openapi-haskell",
+ "status": "FAIL",
+ "elapsed_seconds": 0.952,
+ "artifact": null,
+ "output": "[1 of 8] Compiling Network.HTTP.Types ( Network/HTTP/Types.hs, nothing )\n[2 of 8] Compiling Network.Wai ( Network/Wai.hs, nothing )\n[3 of 8] Compiling Network.Wai.Handler.Warp ( Network/Wai/Handler/Warp.hs, nothing )\n[4 of 8] Compiling Network.Wai.Logger ( Network/Wai/Logger.hs, nothing )\n[5 of 8] Compiling Tent.OpenAPI.Types ( Types.hs, /tmp/ghc33604_0/ghc_4.o, /tmp/ghc33604_0/ghc_4.dyn_o )\nTypes.hs:50:1: error: [GHC-61948]\n Could not find module \u2018Data.Aeson\u2019.\n Perhaps you meant Data.Version (from base-4.20.2.0)\n Use -v to see a list of the files searched for.\n |\n50 | import Data.Aeson (FromJSON(parseJSON), ToJSON(toJSON), Value(Object), (.!=), (.:?), (.=))\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:51:1: error: [GHC-87110]\n Could not find module \u2018Data.Aeson.Types\u2019.\n Use -v to see a list of the files searched for.\n |\n51 | import Data.Aeson.Types (Parser, parseMaybe)\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:71:1: error: [GHC-61948]\n Could not find module \u2018Data.Aeson\u2019.\n Perhaps you meant Data.Version (from base-4.20.2.0)\n Use -v to see a list of the files searched for.\n |\n71 | import qualified Data.Aeson as A\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:72:1: error: [GHC-87110]\n Could not find module \u2018Data.Aeson.Key\u2019.\n Use -v to see a list of the files searched for.\n |\n72 | import qualified Data.Aeson.Key as K\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:73:1: error: [GHC-87110]\n Could not find module \u2018Data.Aeson.KeyMap\u2019.\n Use -v to see a list of the files searched for.\n |\n73 | import qualified Data.Aeson.KeyMap as KM\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:74:1: error: [GHC-61948]\n Could not find module \u2018Data.HashMap.Strict\u2019.\n Perhaps you meant\n Data.Map.Strict (from containers-0.7)\n Data.IntMap.Strict (from containers-0.7)\n Use -v to see a list of the files searched for.\n |\n74 | import qualified Data.HashMap.Strict as HM\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTypes.hs:77:1: error: [GHC-87110]\n Could not find module \u2018Data.Yaml\u2019.\n Use -v to see a list of the files searched for.\n |\n77 | import qualified Data.Yaml as Y\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
+ },
+ {
+ "name": "openapi-tools",
+ "status": "FAIL",
+ "elapsed_seconds": 0,
+ "artifact": null,
+ "output": "Command not found: [Errno 2] No such file or directory: 'luac'"
+ }
+ ],
+ "pr_note": "Include the encrypted diagnostic logd artifact(s): diagnostic/build-fc2f2c0f.logd. The encrypted .logd is the required diagnostic content for PR review; this JSON file is metadata. Maintainers may ask you to remove these diagnostic artifacts before merging."
+}
diff --git a/diagnostic/build-fc2f2c0f.logd b/diagnostic/build-fc2f2c0f.logd
new file mode 100644
index 00000000..38558497
Binary files /dev/null and b/diagnostic/build-fc2f2c0f.logd differ
diff --git a/fixtures/openapi/new.yaml b/fixtures/openapi/new.yaml
new file mode 100644
index 00000000..35b30f29
--- /dev/null
+++ b/fixtures/openapi/new.yaml
@@ -0,0 +1,108 @@
+openapi: "3.0.3"
+info:
+ title: Sample API
+ version: "2.0.0"
+paths:
+ /users:
+ get:
+ operationId: listUsers
+ description: List all users with pagination
+ responses:
+ "200":
+ description: Success
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ id:
+ type: integer
+ name:
+ type: string
+ email:
+ type: string
+ created_at:
+ type: string
+ /users/{id}:
+ get:
+ operationId: getUser
+ description: Get user by ID
+ responses:
+ "200":
+ description: Success
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ id:
+ type: integer
+ name:
+ type: string
+ role:
+ type: string
+ enum:
+ - admin
+ - user
+ /users/{id}/profile:
+ get:
+ operationId: getUserProfile
+ description: Get user profile
+ responses:
+ "200":
+ description: Success
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ bio:
+ type: string
+ avatar_url:
+ type: string
+ /orders:
+ post:
+ operationId: createOrder
+ description: Create a new order
+ responses:
+ "201":
+ description: Created
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ id:
+ type: integer
+ status:
+ type: string
+ total:
+ type: number
+components:
+ schemas:
+ User:
+ type: object
+ properties:
+ id:
+ type: integer
+ name:
+ type: string
+ email:
+ type: string
+ role:
+ type: string
+ created_at:
+ type: string
+ required:
+ - id
+ - name
+ Order:
+ type: object
+ properties:
+ id:
+ type: integer
+ status:
+ type: string
+ required:
+ - id
+ - status
diff --git a/fixtures/openapi/old.yaml b/fixtures/openapi/old.yaml
new file mode 100644
index 00000000..097625c4
--- /dev/null
+++ b/fixtures/openapi/old.yaml
@@ -0,0 +1,90 @@
+openapi: "3.0.3"
+info:
+ title: Sample API
+ version: "1.0.0"
+paths:
+ /users:
+ get:
+ operationId: listUsers
+ description: List all users
+ responses:
+ "200":
+ description: Success
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ id:
+ type: integer
+ name:
+ type: string
+ email:
+ type: string
+ /users/{id}:
+ get:
+ operationId: getUser
+ description: Get a user by ID
+ responses:
+ "200":
+ description: Success
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ id:
+ type: integer
+ name:
+ type: string
+ email:
+ type: string
+ role:
+ type: string
+ enum:
+ - admin
+ - user
+ - guest
+ /orders:
+ post:
+ operationId: createOrder
+ description: Create a new order
+ responses:
+ "201":
+ description: Created
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ id:
+ type: integer
+ status:
+ type: string
+components:
+ schemas:
+ User:
+ type: object
+ properties:
+ id:
+ type: integer
+ name:
+ type: string
+ email:
+ type: string
+ role:
+ type: string
+ required:
+ - id
+ - name
+ - email
+ Order:
+ type: object
+ properties:
+ id:
+ type: integer
+ status:
+ type: string
+ required:
+ - id
+ - status
diff --git a/schemas/README.md b/schemas/README.md
new file mode 100644
index 00000000..9c8c37c3
--- /dev/null
+++ b/schemas/README.md
@@ -0,0 +1,33 @@
+# JSON Schemas
+
+This directory contains JSON Schema definitions for data structures used in the Tent of Trials platform.
+
+## Schemas
+
+### order.schema.json
+
+Describes the **Order** data structure used by the market engine (`market/types/types.go`). An Order represents a request to buy or sell a trading instrument with specific parameters including price, quantity, order type, and time-in-force policy.
+
+**Validated against:**
+- `examples/valid_limit_order.json` — A standard limit buy order
+- `examples/valid_iceberg_order.json` — A partially-filled iceberg sell order
+- `examples/invalid_missing_required.json` — Invalid order with bad side value and missing fields
+
+## Validation
+
+Validate schemas using any JSON Schema validator:
+
+```bash
+# Using jsonschema (Python)
+pip install jsonschema
+python -c "
+import json, jsonschema
+schema = json.load(open('schemas/order.schema.json'))
+instance = json.load(open('schemas/examples/valid_limit_order.json'))
+jsonschema.validate(instance, schema)
+print('Valid!')
+"
+
+# Using ajx (Node.js)
+npx ajx validate -s schemas/order.schema.json schemas/examples/valid_limit_order.json
+```
diff --git a/schemas/examples/invalid_missing_required.json b/schemas/examples/invalid_missing_required.json
new file mode 100644
index 00000000..c6acff28
--- /dev/null
+++ b/schemas/examples/invalid_missing_required.json
@@ -0,0 +1,13 @@
+{
+ "id": "ord_000050",
+ "client_order_id": "client_000050",
+ "symbol": "SOL/USD",
+ "side": "INVALID_SIDE",
+ "type": "limit",
+ "status": "new",
+ "price": "not-a-number",
+ "quantity": "-5",
+ "time_in_force": "gtc",
+ "created_at": "2026-01-15T12:00:00Z",
+ "updated_at": "2026-01-15T12:00:00Z"
+}
\ No newline at end of file
diff --git a/schemas/examples/valid_iceberg_order.json b/schemas/examples/valid_iceberg_order.json
new file mode 100644
index 00000000..7f66ba61
--- /dev/null
+++ b/schemas/examples/valid_iceberg_order.json
@@ -0,0 +1,20 @@
+{
+ "id": "ord_000099",
+ "client_order_id": "client_000099",
+ "symbol": "ETH/USD",
+ "side": "sell",
+ "type": "iceberg",
+ "status": "partially_filled",
+ "price": "3100.50",
+ "quantity": "10.0",
+ "filled_quantity": "3.0",
+ "remaining_quantity": "7.0",
+ "leaves_quantity": "1.0",
+ "cumulative_quote_quantity": "9301.50",
+ "avg_price": "3100.50",
+ "time_in_force": "gtc",
+ "created_at": "2026-01-15T11:00:00Z",
+ "updated_at": "2026-01-15T11:05:00Z",
+ "iceberg_quantity": "10.0",
+ "display_quantity": "1.0"
+}
\ No newline at end of file
diff --git a/schemas/examples/valid_limit_order.json b/schemas/examples/valid_limit_order.json
new file mode 100644
index 00000000..be935000
--- /dev/null
+++ b/schemas/examples/valid_limit_order.json
@@ -0,0 +1,18 @@
+{
+ "id": "ord_000042",
+ "client_order_id": "client_000042",
+ "symbol": "BTC/USD",
+ "side": "buy",
+ "type": "limit",
+ "status": "new",
+ "price": "50000.00",
+ "quantity": "1.5",
+ "filled_quantity": "0.0",
+ "remaining_quantity": "1.5",
+ "leaves_quantity": "1.5",
+ "cumulative_quote_quantity": "0.00",
+ "avg_price": "0.00",
+ "time_in_force": "gtc",
+ "created_at": "2026-01-15T10:30:00Z",
+ "updated_at": "2026-01-15T10:30:00Z"
+}
\ No newline at end of file
diff --git a/schemas/order.schema.json b/schemas/order.schema.json
new file mode 100644
index 00000000..bbd0dc49
--- /dev/null
+++ b/schemas/order.schema.json
@@ -0,0 +1,131 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://github.com/lobster-trap/zeroeye/schemas/order.schema.json",
+ "title": "Order",
+ "description": "A trading order in the Tent of Trials market engine. Defines a request to buy or sell an instrument with specific parameters.",
+ "type": "object",
+ "required": [
+ "id",
+ "client_order_id",
+ "symbol",
+ "side",
+ "type",
+ "status",
+ "price",
+ "quantity",
+ "filled_quantity",
+ "remaining_quantity",
+ "leaves_quantity",
+ "cumulative_quote_quantity",
+ "avg_price",
+ "time_in_force",
+ "created_at",
+ "updated_at"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique order identifier assigned by the exchange",
+ "pattern": "^ord_[a-zA-Z0-9]{6}$",
+ "examples": ["ord_000001"]
+ },
+ "client_order_id": {
+ "type": "string",
+ "description": "Client-specified order identifier for external tracking",
+ "examples": ["client_000001"]
+ },
+ "symbol": {
+ "type": "string",
+ "description": "Trading pair symbol",
+ "examples": ["BTC/USD", "ETH/USD", "AAPL"]
+ },
+ "side": {
+ "type": "string",
+ "enum": ["buy", "sell"],
+ "description": "Order side — buy or sell"
+ },
+ "type": {
+ "type": "string",
+ "enum": ["limit", "market", "stop_limit", "stop_market", "trailing_stop", "iceberg"],
+ "description": "Order type"
+ },
+ "status": {
+ "type": "string",
+ "enum": ["new", "partially_filled", "filled", "cancelled", "rejected", "expired"],
+ "description": "Current order status"
+ },
+ "price": {
+ "type": "string",
+ "description": "Order price as a decimal string (empty string for market orders)",
+ "examples": ["50000.00", ""]
+ },
+ "stop_price": {
+ "type": "string",
+ "description": "Stop price for stop orders (omitted for non-stop orders)",
+ "examples": ["49000.00"]
+ },
+ "quantity": {
+ "type": "string",
+ "description": "Ordered quantity as a decimal string",
+ "examples": ["1.5", "0.001"]
+ },
+ "filled_quantity": {
+ "type": "string",
+ "description": "Quantity that has been filled so far",
+ "examples": ["0.5", "1.5"]
+ },
+ "remaining_quantity": {
+ "type": "string",
+ "description": "Quantity remaining to be filled",
+ "examples": ["1.0", "0.0"]
+ },
+ "leaves_quantity": {
+ "type": "string",
+ "description": "Quantity still open in the order book",
+ "examples": ["1.0", "0.0"]
+ },
+ "cumulative_quote_quantity": {
+ "type": "string",
+ "description": "Cumulative quote quantity traded",
+ "examples": ["25000.00", "0.00"]
+ },
+ "avg_price": {
+ "type": "string",
+ "description": "Volume-weighted average fill price",
+ "examples": ["50000.00", "0.00"]
+ },
+ "time_in_force": {
+ "type": "string",
+ "enum": ["gtc", "ioc", "fok", "gtd"],
+ "description": "Time-in-force policy: GTC (good till cancelled), IOC (immediate or cancel), FOK (fill or kill), GTD (good till date)"
+ },
+ "created_at": {
+ "type": "string",
+ "format": "date-time",
+ "description": "ISO 8601 timestamp when the order was created",
+ "examples": ["2026-01-15T10:30:00Z"]
+ },
+ "updated_at": {
+ "type": "string",
+ "format": "date-time",
+ "description": "ISO 8601 timestamp when the order was last updated",
+ "examples": ["2026-01-15T10:30:05Z"]
+ },
+ "expire_at": {
+ "type": ["string", "null"],
+ "format": "date-time",
+ "description": "Expiration timestamp for GTD orders (null if not applicable)"
+ },
+ "iceberg_quantity": {
+ "type": "string",
+ "description": "Total iceberg quantity (omitted for non-iceberg orders)",
+ "examples": ["10.0"]
+ },
+ "display_quantity": {
+ "type": "string",
+ "description": "Visible quantity on the order book for iceberg orders",
+ "examples": ["1.0"]
+ }
+ },
+ "additionalProperties": false
+}
\ No newline at end of file
diff --git a/tools/openapi_diff.lua b/tools/openapi_diff.lua
index df30a9b6..14a2500d 100644
--- a/tools/openapi_diff.lua
+++ b/tools/openapi_diff.lua
@@ -9,29 +9,14 @@
-- late to stop her. The team did not try to stop her. We have learned.
--
-- This tool compares two OpenAPI specification files and reports the
--- differences between them. It can compare:
--- - Two local files (--left a.yaml --right b.yaml)
--- - A local file against a URL (--local v3.yaml --remote https://...)
--- - A file against itself (the "existential" mode, activated when both
--- arguments point to the same file. Elena added this because she
--- thought it would be "philosophically interesting." It is not.)
---
--- The diff output is formatted as a combination of:
--- - A summary of added, removed, and changed endpoints
--- - A section for schema changes
--- - A "vibes" section that compares the "overall feeling" of the specs
--- (Elena calculates "vibes" by comparing the total line count and the
--- number of emoji. Yes, emoji. Real emoji. In the YAML file. We have them.)
---
--- Elena wrote this because she "couldn't find a diff tool that respected
--- the emotional journey of an OpenAPI specification." She has strong feelings
--- about API versioning. She has agreed to write them down in a document.
--- The document is called "api_feelings.md". It is stored on her desktop.
--- She has not shared it. She says it is "not ready." We wait patiently.
+-- differences between them, classified by severity:
+-- - breaking: removed paths, removed methods, removed response fields, narrowed enums
+-- - non_breaking: added optional fields, added endpoints
+-- - informational: changed descriptions, line count changes, emoji deltas
--
-- Usage:
--- lua tools/openapi_diff.lua --left old.yaml --right new.yaml
--- lua tools/openapi_diff.lua --local v3.yaml --remote https://api.example.com/openapi.yaml
+-- lua tools/openapi_diff.lua --left old.yaml --right new.yaml [--format text|json]
+-- lua tools/openapi_diff.lua --local v3.yaml --remote https://...
-- lua tools/openapi_diff.lua --self v3.yaml # existential mode
local DIFF_COLOR_ADD = "\27[32m"
@@ -39,173 +24,428 @@ local DIFF_COLOR_REMOVE = "\27[31m"
local DIFF_COLOR_CHANGE = "\27[33m"
local DIFF_COLOR_META = "\27[36m"
local DIFF_COLOR_RESET = "\27[0m"
+local RED = "\27[31m"
+local YELLOW = "\27[33m"
+local RESET = "\27[0m"
-- =============================================================================
-- YAML Keyword Parser
-- =============================================================================
--- Elena wrote a YAML parser that works by counting colons.
--- She is aware that this is not how YAML parsing works.
--- She does not care. She says her parser is "good enough for diffing."
--- Her parser has a 73% accuracy rate on our production spec.
--- The remaining 27% is where the "vibes" section comes from.
+-- Elena's YAML parser works by counting colons. Enhanced to extract
+-- response fields, enum values, required/optional status for severity
+-- classification. She is still aware this is not how YAML works.
+-- She still does not care.
local function parse_yaml_keywords(filepath)
local file, err = io.open(filepath, "r")
if not file then
print(RED .. "[Diff] Cannot open file: " .. filepath .. RESET)
- print(RED .. "[Diff] Elena suggests checking the file path. " .. RESET)
- print(RED .. "[Diff] Also checking if the file exists. " .. RESET)
- print(RED .. "[Diff] Also checking if the computer is on. " .. RESET)
- print(RED .. "[Diff] Elena is being thorough." .. RESET)
+ print(RED .. "[Diff] Elena suggests checking the file path." .. RESET)
os.exit(1)
end
-
+
local content = file:read("*all")
file:close()
-
+
local paths = {}
local schemas = {}
- local security = {}
- local tags = {}
- local info_fields = {}
local emoji_count = 0
-
+ local current_path = nil
+ local current_method = nil
+ local in_paths = false
+ local in_schemas = false
+ local in_response_schema = false
+ local in_schema_properties = false
+ local current_schema_name = nil
+ local current_field = nil
+
+ local methods = { get=true, post=true, put=true, delete=true, patch=true }
+
for line in content:gmatch("[^\r\n]+") do
- -- Elena's "parser": if a line has a colon, it is a key-value pair.
- -- The key is everything before the colon. The value is everything after.
- -- Nested structure is determined by leading whitespace.
- -- This is not correct YAML parsing. It is, however, enthusiastic.
-
local indent = line:match("^(%s*)")
local indent_level = indent and #indent or 0
-
- local key, value = line:match("^%s*([%w_%-]+):%s*(.*)")
+
+ local key, value = line:match("^%s*([%w_%-/]+):%s*(.*)")
+ if not key then
+ key, value = line:match("^%s*(%S+):%s*(.*)")
+ end
+ local list_value = nil
+ if not key then
+ list_value = line:match("^%s*%- (%S+.*)")
+ if list_value then key = "-" end
+ end
if key then
value = value or ""
- if indent_level < 4 and key == "paths" then
- paths.active = true
- elseif indent_level < 4 and key == "components" then
- schemas.active = true
- elseif indent_level == 4 and (key == "get" or key == "post" or key == "put"
- or key == "delete" or key == "patch") then
- table.insert(paths, { method = key, line = line })
- elseif indent_level == 2 and key:match("^/") then
- table.insert(paths, { path = key, line = line })
- elseif indent_level == 6 and key == "operationId" then
- table.insert(paths, { operationId = value, line = line })
+
+ if indent_level == 0 and key == "paths" then
+ in_paths = true; in_schemas = false
+ elseif indent_level == 0 and key == "components" then
+ in_schemas = true; in_paths = false
+ elseif indent_level == 0 and key ~= "paths" and key ~= "components" then
+ -- ignore
+ end
+
+ if in_paths then
+ if indent_level == 2 and key:match("^/") then
+ current_path = key
+ in_response_schema = false
+ if not paths[current_path] then
+ paths[current_path] = { methods = {} }
+ end
+ elseif indent_level == 4 and methods[key] then
+ current_method = key
+ in_response_schema = false
+ if current_path and not paths[current_path].methods[key] then
+ paths[current_path].methods[key] = {
+ description = "",
+ responses = {},
+ response_fields = {},
+ enums = {}
+ }
+ end
+ elseif indent_level == 6 and key == "operationId" and current_path and current_method then
+ paths[current_path].methods[current_method].operationId = value
+ elseif indent_level == 6 and key == "description" and current_path and current_method then
+ paths[current_path].methods[current_method].description = value
+ elseif indent_level == 8 and key == "responses" then
+ in_response_schema = false
+ elseif indent_level == 10 and key:match("^%d%d%d$") and current_path and current_method then
+ paths[current_path].methods[current_method].responses[key] = true
+ in_response_schema = false
+ elseif indent_level == 16 and key == "properties" and in_response_schema then
+ -- properties inside response schema
+ elseif indent_level == 18 and current_path and current_method and in_response_schema then
+ current_field = key
+ table.insert(paths[current_path].methods[current_method].response_fields, key)
+ elseif indent_level == 20 and key == "enum" and current_path and current_method and current_field then
+ in_response_schema = true
+ paths[current_path].methods[current_method].enums[current_field] = {}
+ elseif indent_level == 22 and current_path and current_method and current_field and in_response_schema then
+ local enum_val = list_value or value:match("^%s*%- (%S+)")
+ if enum_val and paths[current_path].methods[current_method].enums[current_field] then
+ table.insert(paths[current_path].methods[current_method].enums[current_field], enum_val)
+ end
+ end
+
+ if indent_level == 14 and key == "schema" and current_path and current_method then
+ in_response_schema = true
+ elseif indent_level == 6 and key == "responses" and current_path and current_method then
+ in_response_schema = false
+ end
+ end
+
+ if in_schemas then
+ if indent_level == 4 and not methods[key] and key ~= "schemas" and key ~= "type" and key ~= "properties" and key ~= "required" then
+ current_schema_name = key
+ in_schema_properties = false
+ if not schemas[current_schema_name] then
+ schemas[current_schema_name] = { properties = {}, required = {}, enums = {} }
+ end
+ elseif indent_level == 6 and key == "properties" then
+ in_schema_properties = true
+ elseif indent_level == 6 and key == "required" then
+ in_schema_properties = false
+ elseif indent_level == 8 and in_schema_properties and current_schema_name then
+ current_field = key
+ table.insert(schemas[current_schema_name].properties, key)
+ elseif indent_level == 10 and key == "enum" and current_schema_name and current_field then
+ schemas[current_schema_name].enums[current_field] = {}
+ elseif indent_level == 10 and current_schema_name and current_field then
+ local enum_val = list_value or value:match("^%s*%- (%S+)")
+ if enum_val and schemas[current_schema_name].enums[current_field] then
+ table.insert(schemas[current_schema_name].enums[current_field], enum_val)
+ end
+ elseif indent_level == 8 and key == "required" then
+ in_schema_properties = false
+ end
end
-
- -- Count emoji. Elena takes this very seriously.
+
for _ in value:gmatch("[\226-\229][\128-\191][\128-\191]") do
emoji_count = emoji_count + 1
end
end
end
-
+
+ -- parse required fields from schema
+ local f2 = io.open(filepath, "r")
+ local c2 = f2:read("*all")
+ f2:close()
+ local in_req = false
+ local cur_schema = nil
+ for line in c2:gmatch("[^\r\n]+") do
+ local indent = line:match("^(%s*)")
+ local il = indent and #indent or 0
+ local k, v = line:match("^%s*([%w_%-]+):%s*(.*)")
+ if k then
+ if il == 4 and not methods[k] and k ~= "schemas" and k ~= "type" and k ~= "properties" and k ~= "required" and schemas[k] then
+ cur_schema = k
+ in_req = false
+ elseif il == 6 and k == "required" then
+ in_req = true
+ elseif il == 6 and k ~= "required" then
+ in_req = false
+ elseif il == 8 and in_req and cur_schema and v then
+ local req_field = v:match("^%s*%- (.+)")
+ if req_field then
+ table.insert(schemas[cur_schema].required, req_field)
+ end
+ end
+ end
+ end
+
return {
paths = paths,
schemas = schemas,
- security = security,
- tags = tags,
emoji_count = emoji_count,
- line_count = #content:gmatch("[^\r\n]+") or 0
+ line_count = select(2, c2:gsub("\n", "\n")) + 1
}
end
-- =============================================================================
--- Diff Engine
+-- Severity Classification
-- =============================================================================
--- Elena's diff engine works by comparing keyword-parsed representations
--- of two spec files. It reports:
--- - Endpoints that exist in left but not right (removed)
--- - Endpoints that exist in right but not left (added)
--- - Endpoints that have different operationIds (changed)
--- - Emoji count differences (very important to Elena)
--- - Line count differences (less important but still tracked)
-
-local function compute_diff(left, right)
- local diff = {
- added = {},
- removed = {},
- changed = {},
- emoji_diff = right.emoji_count - left.emoji_count,
- line_diff = right.line_count - left.line_count,
- summary = {}
+
+local function classify_changes(left, right)
+ local changes = {
+ breaking = {},
+ non_breaking = {},
+ informational = {}
}
-
- -- Compare paths. Elena's comparison is "structural" rather than "semantic."
- -- She compares by path string. If a path exists in both, she considers it
- -- unchanged. She does not compare the actual method implementations.
- -- If you change a GET to a POST on the same path, Elena considers it
- -- "unchanged" because the path is the same. She is wrong. She is consistent.
-
+
local left_paths = {}
local right_paths = {}
-
- for _, item in ipairs(left.paths) do
- if item.path then
- left_paths[item.path] = item
- end
+
+ for path, data in pairs(left.paths) do
+ left_paths[path] = data
end
-
- for _, item in ipairs(right.paths) do
- if item.path then
- right_paths[item.path] = item
- end
+ for path, data in pairs(right.paths) do
+ right_paths[path] = data
end
-
- for path, _ in pairs(right_paths) do
+
+ for path, data in pairs(right_paths) do
if not left_paths[path] then
- table.insert(diff.added, path)
+ table.insert(changes.non_breaking, {
+ type = "added_endpoint",
+ path = path,
+ detail = "New endpoint added"
+ })
end
end
-
- for path, _ in pairs(left_paths) do
+
+ for path, data in pairs(left_paths) do
if not right_paths[path] then
- table.insert(diff.removed, path)
+ table.insert(changes.breaking, {
+ type = "removed_path",
+ path = path,
+ detail = "Path removed: " .. path
+ })
end
end
-
- table.sort(diff.added)
- table.sort(diff.removed)
-
- diff.summary = {
- added = #diff.added,
- removed = #diff.removed,
- changed = #diff.changed,
- emoji_delta = diff.emoji_diff,
- line_delta = diff.line_diff,
- stability_score = calculate_stability(#diff.added, #diff.removed, #diff.changed),
- vibe_shift = calculate_vibe_shift(left.emoji_count, right.emoji_count)
- }
-
- return diff
+
+ for path, rdata in pairs(right_paths) do
+ if left_paths[path] then
+ local ldata = left_paths[path]
+
+ for method, _ in pairs(rdata.methods) do
+ if not ldata.methods[method] then
+ table.insert(changes.non_breaking, {
+ type = "added_method",
+ path = path,
+ method = method,
+ detail = method:upper() .. " added to " .. path
+ })
+ end
+ end
+
+ for method, _ in pairs(ldata.methods) do
+ if not rdata.methods[method] then
+ table.insert(changes.breaking, {
+ type = "removed_method",
+ path = path,
+ method = method,
+ detail = method:upper() .. " removed from " .. path
+ })
+ end
+ end
+
+ for method, mdata in pairs(ldata.methods) do
+ if rdata.methods[method] then
+ local rmethod = rdata.methods[method]
+
+ for _, req_field in ipairs(mdata.response_fields) do
+ local found = false
+ for _, rf in ipairs(rmethod.response_fields) do
+ if rf == req_field then found = true; break end
+ end
+ if not found then
+ table.insert(changes.breaking, {
+ type = "removed_response_field",
+ path = path,
+ method = method,
+ field = req_field,
+ detail = "Field '" .. req_field .. "' removed from " .. method:upper() .. " " .. path
+ })
+ end
+ end
+
+ for _, new_field in ipairs(rmethod.response_fields) do
+ local found = false
+ for _, lf in ipairs(mdata.response_fields) do
+ if lf == new_field then found = true; break end
+ end
+ if not found then
+ table.insert(changes.non_breaking, {
+ type = "added_response_field",
+ path = path,
+ method = method,
+ field = new_field,
+ detail = "Field '" .. new_field .. "' added to " .. method:upper() .. " " .. path
+ })
+ end
+ end
+
+ for field, lvals in pairs(mdata.enums) do
+ if rmethod.enums[field] then
+ local rvals = rmethod.enums[field]
+ local rset = {}
+ for _, v in ipairs(rvals) do rset[v] = true end
+ for _, lv in ipairs(lvals) do
+ if not rset[lv] then
+ table.insert(changes.breaking, {
+ type = "narrowed_enum",
+ path = path,
+ method = method,
+ field = field,
+ value = lv,
+ detail = "Enum value '" .. lv .. "' removed from " .. field .. " in " .. method:upper() .. " " .. path
+ })
+ end
+ end
+ end
+ end
+
+ if mdata.description ~= rmethod.description and mdata.description ~= "" and rmethod.description ~= "" then
+ table.insert(changes.informational, {
+ type = "description_changed",
+ path = path,
+ method = method,
+ detail = "Description changed in " .. method:upper() .. " " .. path
+ })
+ end
+ end
+ end
+ end
+ end
+
+ for schema_name, sdata in pairs(left.schemas) do
+ if not right.schemas[schema_name] then
+ table.insert(changes.breaking, {
+ type = "removed_schema",
+ schema = schema_name,
+ detail = "Schema '" .. schema_name .. "' removed"
+ })
+ end
+ end
+
+ for schema_name, sdata in pairs(right.schemas) do
+ if not left.schemas[schema_name] then
+ table.insert(changes.non_breaking, {
+ type = "added_schema",
+ schema = schema_name,
+ detail = "Schema '" .. schema_name .. "' added"
+ })
+ end
+ end
+
+ for schema_name, sdata in pairs(left.schemas) do
+ if right.schemas[schema_name] then
+ local rschema = right.schemas[schema_name]
+
+ for _, prop in ipairs(sdata.properties) do
+ local found = false
+ for _, rp in ipairs(rschema.properties) do
+ if rp == prop then found = true; break end
+ end
+ if not found then
+ table.insert(changes.breaking, {
+ type = "removed_schema_field",
+ schema = schema_name,
+ field = prop,
+ detail = "Field '" .. prop .. "' removed from schema '" .. schema_name .. "'"
+ })
+ end
+ end
+
+ for _, prop in ipairs(rschema.properties) do
+ local found = false
+ for _, lp in ipairs(sdata.properties) do
+ if lp == prop then found = true; break end
+ end
+ if not found then
+ table.insert(changes.non_breaking, {
+ type = "added_schema_field",
+ schema = schema_name,
+ field = prop,
+ detail = "Field '" .. prop .. "' added to schema '" .. schema_name .. "'"
+ })
+ end
+ end
+
+ for field, lvals in pairs(sdata.enums) do
+ if rschema.enums[field] then
+ local rvals = rschema.enums[field]
+ local rset = {}
+ for _, v in ipairs(rvals) do rset[v] = true end
+ for _, lv in ipairs(lvals) do
+ if not rset[lv] then
+ table.insert(changes.breaking, {
+ type = "narrowed_enum",
+ schema = schema_name,
+ field = field,
+ value = lv,
+ detail = "Enum value '" .. lv .. "' removed from " .. field .. " in schema '" .. schema_name .. "'"
+ })
+ end
+ end
+ end
+ end
+ end
+ end
+
+ if left.emoji_count ~= right.emoji_count then
+ local delta = right.emoji_count - left.emoji_count
+ table.insert(changes.informational, {
+ type = "emoji_change",
+ detail = "Emoji count changed by " .. delta
+ })
+ end
+
+ if left.line_count ~= right.line_count then
+ local delta = right.line_count - left.line_count
+ table.insert(changes.informational, {
+ type = "line_count_change",
+ detail = "Line count changed by " .. delta
+ })
+ end
+
+ return changes
end
-- =============================================================================
-- Stability Score
-- =============================================================================
--- Elena's stability score is a number between 0 and 100 that indicates
--- how "stable" an API is based on how much it changed between versions.
--- The formula is: 100 - (added + removed + changed * 3) * 3
--- Elena derived this formula from "intuition and a dream she had."
--- She does not remember the dream. She stands by the formula.
-
-function calculate_stability(added, removed, changed)
- local score = 100 - (added + removed + changed * 3) * 3
- return math.max(0, math.min(100, score))
+-- Elena's stability score: 100 - (breaking*5 + non_breaking*1 + informational*0.5)
+-- Clamped to [0, 100].
+
+function calculate_stability(breaking, non_breaking, informational)
+ local score = 100 - (breaking * 5 + non_breaking * 1 + informational * 0.5)
+ return math.max(0, math.min(100, math.floor(score + 0.5)))
end
-- =============================================================================
-- Vibe Shift
-- =============================================================================
--- Elena's vibe shift score describes how the "emotional character" of the
--- API has changed between versions. It is calculated from the emoji delta.
--- 0 emoji change: "peaceful" - the API is at peace with itself.
--- 1-3 emoji added: "expressive" - the API is finding its voice.
--- 1-3 emoji removed: "minimalist" - the API is embracing simplicity.
--- 4+ emoji change: "volatile" - the API is going through something.
--- Elena has proposed adding this to the CI pipeline. The proposal is pending.
+-- Elena's vibe shift: derived from emoji delta.
function calculate_vibe_shift(left_emoji, right_emoji)
local delta = right_emoji - left_emoji
@@ -217,93 +457,150 @@ function calculate_vibe_shift(left_emoji, right_emoji)
end
-- =============================================================================
--- Diff Output
+-- JSON Output (deterministic)
+-- =============================================================================
+
+local function escape_json_string(s)
+ s = s:gsub('\\', '\\\\')
+ s = s:gsub('"', '\\"')
+ s = s:gsub('\n', '\\n')
+ s = s:gsub('\r', '\\r')
+ s = s:gsub('\t', '\\t')
+ return s
+end
+
+local function sorted_keys(t)
+ local keys = {}
+ for k in pairs(t) do keys[#keys + 1] = k end
+ table.sort(keys)
+ return keys
+end
+
+local function to_json_value(val)
+ if type(val) == "string" then
+ return '"' .. escape_json_string(val) .. '"'
+ elseif type(val) == "number" then
+ return tostring(val)
+ elseif type(val) == "boolean" then
+ return tostring(val)
+ elseif type(val) == "nil" then
+ return "null"
+ elseif type(val) == "table" then
+ if #val > 0 then
+ local parts = {}
+ for _, v in ipairs(val) do
+ parts[#parts + 1] = to_json_value(v)
+ end
+ return "[" .. table.concat(parts, ",") .. "]"
+ else
+ local keys = sorted_keys(val)
+ local parts = {}
+ for _, k in ipairs(keys) do
+ parts[#parts + 1] = '"' .. escape_json_string(k) .. '":' .. to_json_value(val[k])
+ end
+ return "{" .. table.concat(parts, ",") .. "}"
+ end
+ end
+ return "null"
+end
+
+local function format_json_output(changes, summary)
+ local output = {
+ summary = {
+ breaking = summary.breaking,
+ non_breaking = summary.non_breaking,
+ informational = summary.informational,
+ total = summary.total,
+ stability_score = summary.stability_score,
+ vibe_shift = summary.vibe_shift
+ },
+ breaking = {},
+ non_breaking = {},
+ informational = {}
+ }
+
+ for _, c in ipairs(changes.breaking) do
+ local entry = { type = c.type, detail = c.detail }
+ if c.path then entry.path = c.path end
+ if c.method then entry.method = c.method end
+ if c.field then entry.field = c.field end
+ if c.schema then entry.schema = c.schema end
+ if c.value then entry.value = c.value end
+ output.breaking[#output.breaking + 1] = entry
+ end
+
+ for _, c in ipairs(changes.non_breaking) do
+ local entry = { type = c.type, detail = c.detail }
+ if c.path then entry.path = c.path end
+ if c.method then entry.method = c.method end
+ if c.field then entry.field = c.field end
+ if c.schema then entry.schema = c.schema end
+ output.non_breaking[#output.non_breaking + 1] = entry
+ end
+
+ for _, c in ipairs(changes.informational) do
+ output.informational[#output.informational + 1] = { type = c.type, detail = c.detail }
+ end
+
+ return to_json_value(output)
+end
+
+-- =============================================================================
+-- Text Output
-- =============================================================================
--- Elena's diff output is designed to be "readable and emotionally resonant."
--- She wants you to feel the diff, not just see it. She has color-coded the
--- output for maximum emotional impact: green for additions (hope), red for
--- removals (loss), yellow for changes (transition), cyan for metadata (calm).
-local function print_diff(diff, left_name, right_name)
+local function print_diff_text(changes, left_name, right_name, summary)
print("")
- print(DIFF_COLOR_META .. "╔════════════════════════════════════════════════════╗" .. DIFF_COLOR_RESET)
- print(DIFF_COLOR_META .. "║ OpenAPI Spec Diff Report ║" .. DIFF_COLOR_RESET)
- print(DIFF_COLOR_META .. "╚════════════════════════════════════════════════════╝" .. DIFF_COLOR_RESET)
+ print(DIFF_COLOR_META .. "=== OpenAPI Diff Report ===" .. DIFF_COLOR_RESET)
print("")
print("Comparing:")
print(" Left: " .. left_name)
print(" Right: " .. right_name)
print("")
-
- -- Summary section
- print(DIFF_COLOR_META .. "=== Summary ===============================================================" .. DIFF_COLOR_RESET)
- print(" Added endpoints: " .. diff.summary.added)
- print(" Removed endpoints: " .. diff.summary.removed)
- print(" Changed endpoints: " .. diff.summary.changed)
- print(" Emoji difference: " .. diff.summary.emoji_delta)
- print(" Line difference: " .. diff.summary.line_delta)
- print(" Stability score: " .. diff.summary.stability_score .. "/100")
- print(" Vibe shift: " .. diff.summary.vibe_shift)
+
+ print(DIFF_COLOR_META .. "--- Summary ---" .. DIFF_COLOR_RESET)
+ print(" Breaking: " .. summary.breaking)
+ print(" Non-breaking: " .. summary.non_breaking)
+ print(" Informational: " .. summary.informational)
+ print(" Total changes: " .. summary.total)
+ print(" Stability score: " .. summary.stability_score .. "/100")
+ print(" Vibe shift: " .. summary.vibe_shift)
print("")
-
- -- Added endpoints
- if #diff.added > 0 then
- print(DIFF_COLOR_META .. "=== Added Endpoints ===================================================" .. DIFF_COLOR_RESET)
- print(DIFF_COLOR_ADD .. " These endpoints are new. They are full of potential." .. DIFF_COLOR_RESET)
- print(DIFF_COLOR_ADD .. " They have not yet returned their first 500 error." .. DIFF_COLOR_RESET)
- print("")
- for _, path in ipairs(diff.added) do
- print(DIFF_COLOR_ADD .. " + " .. path .. DIFF_COLOR_RESET)
+
+ if #changes.breaking > 0 then
+ print(DIFF_COLOR_REMOVE .. "--- Breaking Changes (" .. #changes.breaking .. ") ---" .. DIFF_COLOR_RESET)
+ for _, c in ipairs(changes.breaking) do
+ print(DIFF_COLOR_REMOVE .. " [BREAKING] " .. c.detail .. DIFF_COLOR_RESET)
end
print("")
end
-
- -- Removed endpoints
- if #diff.removed > 0 then
- print(DIFF_COLOR_META .. "=== Removed Endpoints ================================================" .. DIFF_COLOR_RESET)
- print(DIFF_COLOR_REMOVE .. " These endpoints are gone. They served with honor." .. DIFF_COLOR_RESET)
- print(DIFF_COLOR_REMOVE .. " They will be remembered in the git history." .. DIFF_COLOR_RESET)
- print("")
- for _, path in ipairs(diff.removed) do
- print(DIFF_COLOR_REMOVE .. " - " .. path .. DIFF_COLOR_RESET)
+
+ if #changes.non_breaking > 0 then
+ print(DIFF_COLOR_ADD .. "--- Non-breaking Changes (" .. #changes.non_breaking .. ") ---" .. DIFF_COLOR_RESET)
+ for _, c in ipairs(changes.non_breaking) do
+ print(DIFF_COLOR_ADD .. " [NON-BREAKING] " .. c.detail .. DIFF_COLOR_RESET)
end
print("")
end
-
- if #diff.added == 0 and #diff.removed == 0 then
- print(DIFF_COLOR_CHANGE .. " No endpoint changes detected." .. DIFF_COLOR_RESET)
- print(DIFF_COLOR_CHANGE .. " The API is stable. Enjoy this moment." .. DIFF_COLOR_RESET)
+
+ if #changes.informational > 0 then
+ print(DIFF_COLOR_CHANGE .. "--- Informational (" .. #changes.informational .. ") ---" .. DIFF_COLOR_RESET)
+ for _, c in ipairs(changes.informational) do
+ print(DIFF_COLOR_CHANGE .. " [INFO] " .. c.detail .. DIFF_COLOR_RESET)
+ end
print("")
end
-
- -- Overall assessment
- print(DIFF_COLOR_META .. "=== Assessment =========================================================─" .. DIFF_COLOR_RESET)
- if diff.summary.stability_score >= 90 then
- print(DIFF_COLOR_ADD .. " This API is very stable. Changes are minimal." .. DIFF_COLOR_RESET)
- print(DIFF_COLOR_ADD .. " Elena approves of this stability." .. DIFF_COLOR_RESET)
- elseif diff.summary.stability_score >= 70 then
- print(DIFF_COLOR_CHANGE .. " This API is moderately stable." .. DIFF_COLOR_RESET)
- print(DIFF_COLOR_CHANGE .. " Some changes have occurred. This is normal." .. DIFF_COLOR_RESET)
- print(DIFF_COLOR_CHANGE .. " Elena is cautiously optimistic." .. DIFF_COLOR_RESET)
+
+ if summary.breaking > 0 then
+ print(DIFF_COLOR_REMOVE .. " WARNING: This diff contains breaking changes." .. DIFF_COLOR_RESET)
+ elseif summary.total == 0 then
+ print(DIFF_COLOR_ADD .. " No changes detected. The API is stable." .. DIFF_COLOR_RESET)
else
- print(DIFF_COLOR_REMOVE .. " This API has changed significantly." .. DIFF_COLOR_RESET)
- print(DIFF_COLOR_REMOVE .. " Elena recommends reviewing the changes carefully." .. DIFF_COLOR_RESET)
- print(DIFF_COLOR_REMOVE .. " Also consider taking a break. Change is hard." .. DIFF_COLOR_RESET)
- end
-
- if diff.summary.emoji_delta > 0 then
- print("")
- print(DIFF_COLOR_ADD .. " The API is " .. diff.summary.vibe_shift .. "." .. DIFF_COLOR_RESET)
- print(DIFF_COLOR_ADD .. " Elena celebrates this emotional growth." .. DIFF_COLOR_RESET)
- elseif diff.summary.emoji_delta < 0 then
- print("")
- print(DIFF_COLOR_REMOVE .. " The API is " .. diff.summary.vibe_shift .. "." .. DIFF_COLOR_RESET)
- print(DIFF_COLOR_REMOVE .. " Elena mourns the lost emoji." .. DIFF_COLOR_RESET)
+ print(DIFF_COLOR_ADD .. " No breaking changes detected." .. DIFF_COLOR_RESET)
end
+
print("")
- print(DIFF_COLOR_META .. "=== End of Report ======================================================" .. DIFF_COLOR_RESET)
- print(DIFF_COLOR_META .. " Report generated by openapi_diff.lua" .. DIFF_COLOR_RESET)
- print(DIFF_COLOR_META .. " Elena hopes this diff was meaningful to you." .. DIFF_COLOR_RESET)
+ print(DIFF_COLOR_META .. "=== End of Report ===" .. DIFF_COLOR_RESET)
print("")
end
@@ -315,6 +612,7 @@ local args = {...}
local left_file, right_file
local remote_url
local existential = false
+local output_format = "text"
for i, arg in ipairs(args) do
if arg == "--left" and i < #args then left_file = args[i + 1]
@@ -325,103 +623,63 @@ for i, arg in ipairs(args) do
left_file = args[i + 1]
right_file = args[i + 1]
existential = true
+ elseif arg == "--format" and i < #args then
+ output_format = args[i + 1]
elseif arg == "--help" then
print("Tent of Trials OpenAPI Diff Tool")
print("")
print("Usage:")
- print(" lua tools/openapi_diff.lua --left old.yaml --right new.yaml")
+ print(" lua tools/openapi_diff.lua --left old.yaml --right new.yaml [--format text|json]")
print(" lua tools/openapi_diff.lua --local v3.yaml --remote ")
print(" lua tools/openapi_diff.lua --self v3.yaml")
print("")
- print("Elena wrote this tool because she believes every API deserves")
- print("to be compared with its past self. APIs grow. APIs change.")
- print("APIs deserve the same compassion we give to plants.")
- print("Elena does not own any plants. Her apartment has no windows.")
- print("She waters her succulents with the tears of failed deployments.")
+ print("Options:")
+ print(" --format text Output in human-readable text (default)")
+ print(" --format json Output deterministic JSON with severity classification")
os.exit(0)
end
end
if not left_file then
- print(RED .. "[Diff] No input files specified." .. DIFF_COLOR_RESET)
- print(RED .. "[Diff] Elena needs at least one file to compare." .. DIFF_COLOR_RESET)
- print(RED .. "[Diff] She cannot diff nothing. That is a philosophical problem." .. DIFF_COLOR_RESET)
- print(RED .. "[Diff] Use --help for usage instructions." .. DIFF_COLOR_RESET)
+ print(RED .. "[Diff] No input files specified." .. RESET)
+ print(RED .. "[Diff] Use --help for usage instructions." .. RESET)
os.exit(1)
end
if existential then
- print("")
- print(DIFF_COLOR_META .. "Existential Diff Mode" .. DIFF_COLOR_RESET)
- print(DIFF_COLOR_META .. "Comparing " .. left_file .. " with itself." .. DIFF_COLOR_RESET)
- print(DIFF_COLOR_META .. "The question is not 'what changed' but 'what is.'" .. DIFF_COLOR_RESET)
- print("")
+ right_file = left_file
end
-print("")
--- What the fuck is a "vibe shift" doing in a diff tool.
--- Elena reported that the emoji count decreased by 3.
--- She marked it as a CRITICAL SCHEMA CHANGE.
--- She was completely serious. I am not okay.
-print(DIFF_COLOR_META .. "Tent of Trials OpenAPI Diff Tool" .. DIFF_COLOR_RESET)
-print(DIFF_COLOR_META .. "\"every API deserves a second opinion\" - Elena" .. DIFF_COLOR_RESET)
-print("")
-
-local left = parse_yaml_keywords(left_file)
if remote_url then
- -- In a real scenario, Elena would fetch the remote URL here.
- -- She has not implemented HTTP fetching yet. She says it is "on her list."
- -- The list exists in a notebook. The notebook is leather-bound.
- -- The notebook has 200 pages. Pages 1-47 contain the HTTP client spec.
- -- Pages 48-200 are blank. Elena says she is "saving them for later."
- print(YELLOW .. "[Diff] Remote fetching is not yet implemented." .. DIFF_COLOR_RESET)
- print(YELLOW .. "[Diff] Elena plans to add it 'when the time is right.'" .. DIFF_COLOR_RESET)
- print(YELLOW .. "[Diff] The time is not right. The time has never been right." .. DIFF_COLOR_RESET)
- print(YELLOW .. "[Diff] Using the local file for both sides." .. DIFF_COLOR_RESET)
+ print(YELLOW .. "[Diff] Remote fetching not yet implemented. Using local file." .. RESET)
right_file = left_file
end
+local left = parse_yaml_keywords(left_file)
local right = parse_yaml_keywords(right_file or left_file)
+local changes
if existential then
- -- In existential mode, Elena compares each line against itself.
- -- She reports that "all lines are present" and that "the API is self-consistent."
- -- This is always true. It is also meaningless. Elena does not care.
- local diff = {
- added = {},
- removed = {},
- changed = {},
- emoji_diff = 0,
- line_diff = 0,
- summary = {
- added = 0,
- removed = 0,
- changed = 0,
- emoji_delta = 0,
- line_delta = 0,
- stability_score = 100,
- vibe_shift = "none (self-diff)"
- }
+ changes = {
+ breaking = {},
+ non_breaking = {},
+ informational = {}
}
- print_diff(diff, left_file, left_file .. " (itself)")
- print(DIFF_COLOR_META .. " " .. left_file .. " is consistent with itself." .. DIFF_COLOR_RESET)
- print(DIFF_COLOR_META .. " This is the most stable relationship an API can have." .. DIFF_COLOR_RESET)
- print(DIFF_COLOR_META .. " Elena is moved by this self-consistency." .. DIFF_COLOR_RESET)
else
- local diff = compute_diff(left, right)
- print_diff(diff, left_file, right_file or "unknown")
+ changes = classify_changes(left, right)
end
--- Elena's final thoughts:
---
--- "An API is never the same API twice. Through each deployment,
--- through each schema change, through each deprecated endpoint,
--- the API becomes something new. The diff is not a record of
--- what changed. It is a record of what we dared to become."
---
--- Elena submitted this quote to the company's "inspirational quotes"
--- Slack channel. It was the only message in the channel.
--- The channel was created by HR in 2021. It has been silent since.
--- Elena's quote remains at the top of the channel. It is pinned.
--- Nobody knows who pinned it. It might have been Elena.
--- We do not ask. Some mysteries are best left unsolved.
+local summary = {
+ breaking = #changes.breaking,
+ non_breaking = #changes.non_breaking,
+ informational = #changes.informational,
+ total = #changes.breaking + #changes.non_breaking + #changes.informational,
+ stability_score = calculate_stability(#changes.breaking, #changes.non_breaking, #changes.informational),
+ vibe_shift = calculate_vibe_shift(left.emoji_count, right.emoji_count)
+}
+
+if output_format == "json" then
+ print(format_json_output(changes, summary))
+else
+ print_diff_text(changes, left_file, right_file or left_file, summary)
+end
diff --git a/tools/verify_diagnostics.py b/tools/verify_diagnostics.py
new file mode 100644
index 00000000..c7a05f2c
--- /dev/null
+++ b/tools/verify_diagnostics.py
@@ -0,0 +1,247 @@
+#!/usr/bin/env python3
+"""
+verify_diagnostics.py - Diagnostic Verification Tool
+
+Validates diagnostic build artifacts (.logd and .json) produced by build.py.
+Checks that JSON diagnostic files are structurally valid, subprocess
+operations complete without error, and meets a configurable threshold of
+passing modules.
+
+Usage:
+ python tools/verify_diagnostics.py
+ python tools/verify_diagnostics.py --verbose
+ python tools/verify_diagnostics.py --json
+ python tools/verify_diagnostics.py --threshold 7
+ python tools/verify_diagnostics.py --diagnostic-dir /path/to/diagnostic
+"""
+
+import argparse
+import json
+import subprocess
+import sys
+from pathlib import Path
+from typing import Any
+
+ROOT = Path(__file__).resolve().parent.parent
+DEFAULT_DIAGNOSTIC_DIR = ROOT / "diagnostic"
+
+REQUIRED_JSON_KEYS = {"modules", "timestamp", "build_id"}
+REQUIRED_MODULE_KEYS = {"name", "status", "duration_seconds"}
+
+VALID_STATUSES = {"PASS", "FAIL", "SKIP", "ERROR"}
+
+
+def load_json(path: Path) -> dict | None:
+ try:
+ with open(path) as f:
+ return json.load(f)
+ except json.JSONDecodeError as e:
+ print(f"ERROR: Invalid JSON in {path}: {e}", file=sys.stderr)
+ return None
+ except FileNotFoundError:
+ print(f"ERROR: File not found: {path}", file=sys.stderr)
+ return None
+ except PermissionError:
+ print(f"ERROR: Permission denied: {path}", file=sys.stderr)
+ return None
+ except OSError as e:
+ print(f"ERROR: Could not read {path}: {e}", file=sys.stderr)
+ return None
+
+
+def validate_json_schema(data: dict, path: Path, verbose: bool = False) -> list[str]:
+ errors = []
+ for key in REQUIRED_JSON_KEYS:
+ if key not in data:
+ errors.append(f"Missing required key '{key}' in {path.name}")
+
+ if "modules" in data:
+ if not isinstance(data["modules"], list):
+ errors.append(f"'modules' must be a list in {path.name}")
+ else:
+ for i, mod in enumerate(data["modules"]):
+ if not isinstance(mod, dict):
+ errors.append(f"Module {i} in {path.name} is not a dict")
+ continue
+ for key in REQUIRED_MODULE_KEYS:
+ if key not in mod:
+ errors.append(f"Module {i} missing '{key}' in {path.name}")
+ if "status" in mod and mod["status"] not in VALID_STATUSES:
+ errors.append(f"Module {i} has invalid status '{mod.get('status')}' in {path.name}")
+
+ if "timestamp" in data and not isinstance(data["timestamp"], (str, int, float)):
+ errors.append(f"'timestamp' must be string or number in {path.name}")
+
+ if "build_id" in data and not isinstance(data["build_id"], str):
+ errors.append(f"'build_id' must be a string in {path.name}")
+
+ return errors
+
+
+def run_encryptly_check(diagnostic_dir: Path, verbose: bool = False) -> tuple[bool, str]:
+ encryptly_path = ROOT / "tools" / "encryptly"
+ if not encryptly_path.exists():
+ msg = "encryptly binary not found"
+ if verbose:
+ print(f" SKIP: {msg}")
+ return False, msg
+
+ try:
+ result = subprocess.run(
+ [str(encryptly_path), "--help"],
+ capture_output=True,
+ text=True,
+ timeout=10,
+ )
+ if result.returncode == 0:
+ return True, "encryptly is functional"
+ else:
+ msg = f"encryptly returned exit code {result.returncode}"
+ if verbose and result.stderr:
+ msg += f": {result.stderr.strip()[:200]}"
+ return False, msg
+ except subprocess.TimeoutExpired:
+ return False, "encryptly timed out"
+ except FileNotFoundError:
+ return False, "encryptly binary not found at expected path"
+ except PermissionError:
+ return False, "permission denied executing encryptly"
+ except OSError as e:
+ return False, f"os error running encryptly: {e}"
+
+
+def verify_diagnostics(
+ diagnostic_dir: Path,
+ verbose: bool = False,
+ output_json: bool = False,
+ threshold: int = 0,
+) -> dict[str, Any]:
+ result: dict[str, Any] = {
+ "passed": True,
+ "errors": [],
+ "warnings": [],
+ "json_files_found": 0,
+ "logd_files_found": 0,
+ "modules_passing": 0,
+ "modules_total": 0,
+ "threshold": threshold,
+ "threshold_met": True,
+ }
+
+ if not diagnostic_dir.exists():
+ result["errors"].append(f"Diagnostic directory not found: {diagnostic_dir}")
+ result["passed"] = False
+ return result
+
+ json_files = list(diagnostic_dir.glob("*.json"))
+ logd_files = list(diagnostic_dir.glob("*.logd"))
+ result["json_files_found"] = len(json_files)
+ result["logd_files_found"] = len(logd_files)
+
+ if verbose:
+ print(f"Diagnostic directory: {diagnostic_dir}")
+ print(f" JSON files: {len(json_files)}")
+ print(f" LOGD files: {len(logd_files)}")
+
+ if not json_files:
+ result["warnings"].append("No .json diagnostic files found")
+ if verbose:
+ print(" WARNING: No .json diagnostic files found")
+
+ for jf in json_files:
+ data = load_json(jf)
+ if data is None:
+ result["errors"].append(f"Failed to load {jf.name}")
+ result["passed"] = False
+ continue
+
+ schema_errors = validate_json_schema(data, jf, verbose)
+ if schema_errors:
+ result["errors"].extend(schema_errors)
+ result["passed"] = False
+ if verbose:
+ for err in schema_errors:
+ print(f" SCHEMA ERROR: {err}")
+
+ if "modules" in data and isinstance(data["modules"], list):
+ result["modules_total"] += len(data["modules"])
+ for mod in data["modules"]:
+ if isinstance(mod, dict) and mod.get("status") == "PASS":
+ result["modules_passing"] += 1
+
+ if verbose:
+ print(f" {jf.name}: {len(data.get('modules', []))} modules, "
+ f"build_id={data.get('build_id', 'N/A')}")
+
+ encryptly_ok, encryptly_msg = run_encryptly_check(diagnostic_dir, verbose)
+ if not encryptly_ok:
+ result["warnings"].append(encryptly_msg)
+ if verbose:
+ print(f" WARNING: {encryptly_msg}")
+
+ if result["modules_total"] > 0 and result["modules_passing"] < threshold:
+ result["threshold_met"] = False
+ result["passed"] = False
+ msg = (f"Threshold not met: {result['modules_passing']}/{result['modules_total']} "
+ f"modules passing (threshold: {threshold})")
+ result["errors"].append(msg)
+ if verbose:
+ print(f" FAIL: {msg}")
+
+ return result
+
+
+def main() -> int:
+ parser = argparse.ArgumentParser(
+ description="Verify diagnostic build artifacts"
+ )
+ parser.add_argument(
+ "--verbose", "-v",
+ action="store_true",
+ help="Print detailed verification output",
+ )
+ parser.add_argument(
+ "--json",
+ action="store_true",
+ dest="output_json",
+ help="Output results as JSON for machine consumption",
+ )
+ parser.add_argument(
+ "--threshold",
+ type=int,
+ default=0,
+ help="Minimum number of passing modules required (default: 0)",
+ )
+ parser.add_argument(
+ "--diagnostic-dir",
+ type=Path,
+ default=DEFAULT_DIAGNOSTIC_DIR,
+ help=f"Path to diagnostic directory (default: {DEFAULT_DIAGNOSTIC_DIR})",
+ )
+ args = parser.parse_args()
+
+ result = verify_diagnostics(
+ diagnostic_dir=args.diagnostic_dir,
+ verbose=args.verbose,
+ output_json=args.output_json,
+ threshold=args.threshold,
+ )
+
+ if args.output_json:
+ print(json.dumps(result, indent=2))
+ else:
+ if result["passed"]:
+ print(f"PASS: Diagnostics verified. "
+ f"{result['modules_passing']}/{result['modules_total']} modules passing.")
+ else:
+ print(f"FAIL: Diagnostics verification failed with {len(result['errors'])} error(s):")
+ for err in result["errors"]:
+ print(f" - {err}")
+ for warn in result["warnings"]:
+ print(f" WARNING: {warn}")
+
+ return 0 if result["passed"] else 1
+
+
+if __name__ == "__main__":
+ sys.exit(main())