From fad43026acd0cce2282547ac6318e021c5123762 Mon Sep 17 00:00:00 2001 From: Zack Jackson <25274700+ScriptedAlchemy@users.noreply.github.com> Date: Mon, 26 Oct 2026 12:23:08 -0700 Subject: [PATCH 1/8] chore(release): release 1.0.0-beta.93 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 75 +++++++++++++++++++++++++++++++++++ Cargo.toml | 2 +- server.json | 2 +- version.txt | 2 +- 5 files changed, 79 insertions(+), 4 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 7ddc755b6e..5bc6c50c6a 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "1.0.0-beta.92" + ".": "1.0.0-beta.93" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f77e605e1..dc452817d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,81 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.0.0-beta.93](https://github.com/ScriptedAlchemy/tracedecay/compare/v1.0.0-beta.92...v1.0.0-beta.93) (2026-10-26) + + +### Features + +* **edits:** remove file undo and automatic restoration ([#4472](https://github.com/ScriptedAlchemy/tracedecay/issues/4472)) ([4098533](https://github.com/ScriptedAlchemy/tracedecay/commit/4098533106a89f5e5fe395622e13414314c5c671)) + + +### Bug Fixes + +* **automation:** refuse incomplete stored job documents ([#4468](https://github.com/ScriptedAlchemy/tracedecay/issues/4468)) ([645131b](https://github.com/ScriptedAlchemy/tracedecay/commit/645131b5c338d7e50f02486d3015407017d0ce87)) +* **automation:** retain stable task publication coordination ([bf96210](https://github.com/ScriptedAlchemy/tracedecay/commit/bf962101d773ed92dad400f9efaf8d742398b292)) +* **ci:** bound Windows compiler concurrency ([fadecbd](https://github.com/ScriptedAlchemy/tracedecay/commit/fadecbd811625735291394e88f5fd25de9aa2eef)) +* **ci:** bound Windows compiler concurrency ([518ef74](https://github.com/ScriptedAlchemy/tracedecay/commit/518ef7431cf5649f38af9cdbb6b2760e962eb46f)) +* **ci:** bound Windows compiler concurrency ([5455c4a](https://github.com/ScriptedAlchemy/tracedecay/commit/5455c4a6b89340e6babbd0cfa2cb17d03dacfabd)) +* **ci:** scope native concurrency to Windows ([4ea8661](https://github.com/ScriptedAlchemy/tracedecay/commit/4ea866153115b89aee6bcefd6c7a8bf16a4bdc69)) +* **ci:** scope native concurrency to Windows ([a736653](https://github.com/ScriptedAlchemy/tracedecay/commit/a736653be7f232f012def463bab183fa0251dc2f)) +* **cli:** hold init --wait while the first generation is in flight ([#4494](https://github.com/ScriptedAlchemy/tracedecay/issues/4494)) ([722f7cc](https://github.com/ScriptedAlchemy/tracedecay/commit/722f7ccd83bc42b9cfe3a1dd722a44f97e08eeaa)) +* **code-graph:** pin segment reads within each publication pass ([c04194a](https://github.com/ScriptedAlchemy/tracedecay/commit/c04194aa5e46ef286853e55682b10ec872bd45eb)) +* **code-graph:** pin segment reads within each publication pass ([4806c93](https://github.com/ScriptedAlchemy/tracedecay/commit/4806c934e322da2929d22343d83dff1c4de0ba56)) +* **code-index:** bound cold builds and resume refused publication ([aef1060](https://github.com/ScriptedAlchemy/tracedecay/commit/aef1060d7bf7c0009ff6bc9e812344a5677b5406)) +* **code-index:** bound cold construction and retain refused publication ([3e10b5f](https://github.com/ScriptedAlchemy/tracedecay/commit/3e10b5fbb0a5d49b59c7fbe7216e43c6f10b0a2d)) +* **code-index:** keep a read-reseated graph across parks ([#4499](https://github.com/ScriptedAlchemy/tracedecay/issues/4499)) ([e9a3355](https://github.com/ScriptedAlchemy/tracedecay/commit/e9a3355fa1975ce46f3cd33b640622d92d0aac6d)) +* **code-index:** retry superseded publication fences ([dab12b4](https://github.com/ScriptedAlchemy/tracedecay/commit/dab12b408390013799b790a59687648699c6d0f7)) +* **code-index:** stop a refused cold pass from waking its own retry ([3434b35](https://github.com/ScriptedAlchemy/tracedecay/commit/3434b35c871fc802b3fa4cf9d233e33382390f2c)), closes [#4505](https://github.com/ScriptedAlchemy/tracedecay/issues/4505) +* **cursor:** apply diagnostic caps after lane selection ([#4491](https://github.com/ScriptedAlchemy/tracedecay/issues/4491)) ([96994d0](https://github.com/ScriptedAlchemy/tracedecay/commit/96994d0587c659c98d7c9897ca6b23cd7dbe736a)) +* **evals:** pass the eval self-tests on native Windows ([430e447](https://github.com/ScriptedAlchemy/tracedecay/commit/430e4475095c52ad8b2b0c36821eef32819c9dc6)) +* **evals:** pass the eval self-tests on native Windows ([c6129a6](https://github.com/ScriptedAlchemy/tracedecay/commit/c6129a628e15aac4a4ba3db46d35b67865b1db3b)) +* **extension:** make bridge shutdown terminal ([#4486](https://github.com/ScriptedAlchemy/tracedecay/issues/4486)) ([9b8789c](https://github.com/ScriptedAlchemy/tracedecay/commit/9b8789c94cf9a2d527a680be1e6997f96c057bbb)) +* **graph:** preserve import evidence in caller traversal ([#4509](https://github.com/ScriptedAlchemy/tracedecay/issues/4509)) ([6ed67ce](https://github.com/ScriptedAlchemy/tracedecay/commit/6ed67ce8fde9d45a89ad9a53e9d9982ae251d0e2)) +* **graph:** resolve node ids before waiting on a released catalog ([#4498](https://github.com/ScriptedAlchemy/tracedecay/issues/4498)) ([ba7493d](https://github.com/ScriptedAlchemy/tracedecay/commit/ba7493d0744ea0fd42309286d6bda2c3164f3d8e)) +* **health:** share SCC analysis and count cycle edges exactly ([#4466](https://github.com/ScriptedAlchemy/tracedecay/issues/4466)) ([69ece22](https://github.com/ScriptedAlchemy/tracedecay/commit/69ece22393a0d0039f7f79b79b5d1077d0761ff1)) +* **lcm:** retry timed-out summarizers without a binding change ([59243c2](https://github.com/ScriptedAlchemy/tracedecay/commit/59243c2207583a23d0f52b336529f4ec97c13d71)) +* **lcm:** retry timed-out summarizers without a binding change ([5603495](https://github.com/ScriptedAlchemy/tracedecay/commit/56034958c1d9f913a73555e1ba5e731fe1ae4c83)), closes [#4522](https://github.com/ScriptedAlchemy/tracedecay/issues/4522) +* **privacy:** redact flagged object keys in place ([60c4b85](https://github.com/ScriptedAlchemy/tracedecay/commit/60c4b854699060f6fa2dac77aacc2dcfa1dcdec1)) +* **privacy:** redact flagged object keys in place ([#4515](https://github.com/ScriptedAlchemy/tracedecay/issues/4515)) ([95e49f5](https://github.com/ScriptedAlchemy/tracedecay/commit/95e49f571127750b4aea32b3fe889d20454dd6cc)) +* **privacy:** stop treating compound identifiers as secrets ([36eedb3](https://github.com/ScriptedAlchemy/tracedecay/commit/36eedb3ee7cd127ad6f9106b201df47998e0a2e4)) +* **privacy:** stop treating compound identifiers as secrets ([d869740](https://github.com/ScriptedAlchemy/tracedecay/commit/d869740986811ca92be4c51ab16c3cfdae53562d)), closes [#4451](https://github.com/ScriptedAlchemy/tracedecay/issues/4451) +* **privacy:** verify descendant and repeated key redaction ([08f86e7](https://github.com/ScriptedAlchemy/tracedecay/commit/08f86e73e6aa4b3a27c0c676d65f0c7186849adf)) +* **runtime:** batch session skips and retain preparation writers ([#4495](https://github.com/ScriptedAlchemy/tracedecay/issues/4495)) ([fc598cb](https://github.com/ScriptedAlchemy/tracedecay/commit/fc598cba885191feb2b2d216e83834ea1b8c9de8)) +* **sdk:** bound SSE frames and scan fragmented lines once ([#4501](https://github.com/ScriptedAlchemy/tracedecay/issues/4501)) ([1d7e794](https://github.com/ScriptedAlchemy/tracedecay/commit/1d7e794f0dea4498905564d3ad253548727383ee)) +* **sdk:** own JSON response bodies through cancellation ([#4487](https://github.com/ScriptedAlchemy/tracedecay/issues/4487)) ([ef2809e](https://github.com/ScriptedAlchemy/tracedecay/commit/ef2809ec73e88e4f620a77130892256bd0a4a8b5)) +* **sdk:** refuse enrolled remote redirects ([#4471](https://github.com/ScriptedAlchemy/tracedecay/issues/4471)) ([c9b1d4c](https://github.com/ScriptedAlchemy/tracedecay/commit/c9b1d4c690fcbccdd4cfbf3cafb189d0527fc9d7)) +* **session:** recheck summaries without replaying projection ([d7b7857](https://github.com/ScriptedAlchemy/tracedecay/commit/d7b7857a262a05730db6e25e579c7e23b6b55802)) +* **session:** retain summary work after live projection ([dc524ef](https://github.com/ScriptedAlchemy/tracedecay/commit/dc524ef996bb8233020467f244e4f515afe12a44)) +* **sessions:** keep Pi warning summaries across interrupted scans ([8edc48f](https://github.com/ScriptedAlchemy/tracedecay/commit/8edc48f5014d66e12585d44dade3f28d6ba6d6a5)) +* **sessions:** measure catch-up backlog from source cursors ([#4497](https://github.com/ScriptedAlchemy/tracedecay/issues/4497)) ([f5078ee](https://github.com/ScriptedAlchemy/tracedecay/commit/f5078ee2c32111e3cc900921db02da8ddd40cd0b)) +* **sessions:** mount detached checkouts' session retrieval ([#4496](https://github.com/ScriptedAlchemy/tracedecay/issues/4496)) ([10b5d95](https://github.com/ScriptedAlchemy/tracedecay/commit/10b5d958c87b4b15f8074767da559f544bbb3d8e)) +* **sessions:** resolve Codex scope once, off the polling worker ([#4500](https://github.com/ScriptedAlchemy/tracedecay/issues/4500)) ([4ff7319](https://github.com/ScriptedAlchemy/tracedecay/commit/4ff7319eee248f77cc3f7e44716e7d91a724e202)) +* **sessions:** suppress unchanged Pi discovery summaries ([55b27f9](https://github.com/ScriptedAlchemy/tracedecay/commit/55b27f973e7aec40b4f75aef2f66656e12af7417)) +* **sessions:** suppress unchanged Pi discovery summaries ([f7db15e](https://github.com/ScriptedAlchemy/tracedecay/commit/f7db15e98e5fa47c31f1da36f450bf2fe5f7150d)) +* **source-edit:** insert moved imports at Rust syntax boundaries ([#4516](https://github.com/ScriptedAlchemy/tracedecay/issues/4516)) ([df4ae5c](https://github.com/ScriptedAlchemy/tracedecay/commit/df4ae5c3392802d88d27c0fda92df87130f7db76)) +* **source-edit:** preserve concurrently created destinations ([#4504](https://github.com/ScriptedAlchemy/tracedecay/issues/4504)) ([5d1defa](https://github.com/ScriptedAlchemy/tracedecay/commit/5d1defae526c31db0a737e92b0c81760773bc366)), closes [#4415](https://github.com/ScriptedAlchemy/tracedecay/issues/4415) +* **source-edit:** preserve reexports when moving symbols ([#4493](https://github.com/ScriptedAlchemy/tracedecay/issues/4493)) ([0c9337f](https://github.com/ScriptedAlchemy/tracedecay/commit/0c9337f494f5c9ddabae100df9375e9804b15a2b)) +* **stack:** return shared preflight results directly ([393edb9](https://github.com/ScriptedAlchemy/tracedecay/commit/393edb94d23c19becee38f8849f01ede932759af)) +* **stack:** return shared preflight results directly ([5917017](https://github.com/ScriptedAlchemy/tracedecay/commit/5917017eccd92e05cc104b4d1fc371b05607eec9)) +* **status:** report resident memory no retained owner holds ([#4503](https://github.com/ScriptedAlchemy/tracedecay/issues/4503)) ([c75a45d](https://github.com/ScriptedAlchemy/tracedecay/commit/c75a45d73e0c9d1931e008cd0f2fed3184ba18b0)) +* **status:** report why no GitHub source was observed ([#4492](https://github.com/ScriptedAlchemy/tracedecay/issues/4492)) ([9819426](https://github.com/ScriptedAlchemy/tracedecay/commit/981942674d91d158dde18d01702a8c68cf704c4a)) +* **test:** complete daemon and HTTP fixture teardown ([58949d0](https://github.com/ScriptedAlchemy/tracedecay/commit/58949d0e94e0cb373b45358fa08cb89c732249ef)) +* **test:** drain queued connections before HTTP observation stops ([29f8e25](https://github.com/ScriptedAlchemy/tracedecay/commit/29f8e251f44b8d519070187aec00997d0c6fc3c6)) +* **test:** drain queued connections before HTTP observation stops ([790eeba](https://github.com/ScriptedAlchemy/tracedecay/commit/790eeba2bc4240f4f825172618a768a87f7082ad)) +* **workflow:** remove stale artifact storage size cap ([7ba08c9](https://github.com/ScriptedAlchemy/tracedecay/commit/7ba08c95ccddfc1aae75771d8b85a59f386f2e47)) + + +### Performance Improvements + +* **code-graph:** reread only re-sealed segments when proving a seal ([#4523](https://github.com/ScriptedAlchemy/tracedecay/issues/4523)) ([a201387](https://github.com/ScriptedAlchemy/tracedecay/commit/a201387aab7d14c9c897913f5c4dd77afa202b05)) +* **code-index:** compare an edit's same-named symbols as a set ([6451ced](https://github.com/ScriptedAlchemy/tracedecay/commit/6451ced555a4166d3586db50f81159e7c1c39d06)) +* **code-index:** compare an edit's same-named symbols as a set ([8154ec7](https://github.com/ScriptedAlchemy/tracedecay/commit/8154ec7201c48f8cb86b6f4dff7222a19de2cb58)), closes [#4520](https://github.com/ScriptedAlchemy/tracedecay/issues/4520) + + +### Reverts + +* **privacy:** restore entropy redaction for compound identifiers ([#4512](https://github.com/ScriptedAlchemy/tracedecay/issues/4512)) ([b0c2a1d](https://github.com/ScriptedAlchemy/tracedecay/commit/b0c2a1d0040b32d821b49c9ce44dec541fed030b)) + ## [1.0.0-beta.92](https://github.com/ScriptedAlchemy/tracedecay/compare/v1.0.0-beta.91...v1.0.0-beta.92) (2026-10-23) diff --git a/Cargo.toml b/Cargo.toml index 2638e7ff20..23acebc1f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -64,7 +64,7 @@ resolver = "3" # inheritance table is the sanctioned single source of truth. [workspace.package] edition = "2024" -version = "1.0.0-beta.92" +version = "1.0.0-beta.93" [workspace.dependencies] # nightly-outcome-try is an asupersync default (Outcome's Try impls). It diff --git a/server.json b/server.json index 4b342c0ac3..cc766fd2a5 100644 --- a/server.json +++ b/server.json @@ -8,6 +8,6 @@ "source": "github" }, "websiteUrl": "https://github.com/ScriptedAlchemy/tracedecay", - "version": "1.0.0-beta.92", + "version": "1.0.0-beta.93", "packages": [] } diff --git a/version.txt b/version.txt index 74c9c2b582..a6f112dc62 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.0.0-beta.92 +1.0.0-beta.93 From c5845f6ae5c25191f6fe98024ac0e4a264be9993 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Mon, 26 Oct 2026 19:29:43 +0000 Subject: [PATCH 2/8] chore(release): update generated metadata --- Cargo.lock | 6 +-- crates/tracedecay-cli/BUILD.bazel | 26 ++++++------- crates/tracedecay-project/BUILD.bazel | 10 ++--- crates/tracedecay/BUILD.bazel | 56 +++++++++++++-------------- 4 files changed, 49 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eb823a0d0f..eb80b092f5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6051,7 +6051,7 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracedecay" -version = "1.0.0-beta.92" +version = "1.0.0-beta.93" dependencies = [ "asupersync", "axum", @@ -6329,7 +6329,7 @@ dependencies = [ [[package]] name = "tracedecay-cli" -version = "1.0.0-beta.92" +version = "1.0.0-beta.93" dependencies = [ "asupersync", "aws-lc-rs", @@ -7075,7 +7075,7 @@ dependencies = [ [[package]] name = "tracedecay-project" -version = "1.0.0-beta.92" +version = "1.0.0-beta.93" dependencies = [ "asupersync", "rusqlite", diff --git a/crates/tracedecay-cli/BUILD.bazel b/crates/tracedecay-cli/BUILD.bazel index 54557ecf2a..84740986c3 100644 --- a/crates/tracedecay-cli/BUILD.bazel +++ b/crates/tracedecay-cli/BUILD.bazel @@ -16,7 +16,7 @@ cargo_build_script( deps = all_crate_deps(build = True, build_proc_macro = True) + [], edition = crate_edition(), pkg_name = "tracedecay-cli", - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", crate_features = ["alloc-mimalloc", "default", "production"], data = ["//dashboard:dashboard_sources", "//dashboard:app_dist", "//dashboard:bundle_sha256", "//:version.txt", "//:product_git_sha"], build_script_env = {"TRACEDECAY_DASHBOARD_BUNDLE_SHA256_FILE": "$(location //dashboard:bundle_sha256)", "TRACEDECAY_DASHBOARD_DIST_DIR": "$(location //dashboard:app_dist)", "TRACEDECAY_RELEASE_GIT_SHA_FILE": "$(location //:product_git_sha)", "TRACEDECAY_SKIP_DASHBOARD_BUILD": "1"}, @@ -28,7 +28,7 @@ rust_binary( crate_root = "src/main.rs", edition = crate_edition(), compile_data = glob(["src/**/*"], exclude=["src/**/*.rs"], allow_empty = True), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True) + ["//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+token-counting__d3efa111d08", "//crates/tracedecay-api:tracedecay-api", "//crates/tracedecay-application:tracedecay-application__d28025fc7f4", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__d6c8a9b65c3", "//crates/tracedecay-code-index:tracedecay-code-index__-default_-medium__d6a7dfc4236", "//crates/tracedecay-configuration:tracedecay-configuration__d164684aea6", "//crates/tracedecay-contracts:tracedecay-contracts", "//crates/tracedecay-daemon-control:tracedecay-daemon-control", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__dbf22c08471", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+token-counting__d46dac835a8", "//crates/tracedecay-domain:tracedecay-domain", "//crates/tracedecay-framing:tracedecay-framing", "//crates/tracedecay-global-db:tracedecay-global-db__d1d92290ab9", "//crates/tracedecay-hooks:tracedecay-hooks", "//crates/tracedecay-host-integration:tracedecay-host-integration", "//crates/tracedecay-lsp:tracedecay-lsp__da530592200", "//crates/tracedecay-maintenance:tracedecay-maintenance__dadd78a188f", "//crates/tracedecay-mcp:tracedecay-mcp__d835a4acdac", "//crates/tracedecay-private-fs:tracedecay-private-fs", "//crates/tracedecay-project:tracedecay-project__dca7a3b3082", "//crates/tracedecay-runtime-core:tracedecay-runtime-core", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime", "//crates/tracedecay-sdk:tracedecay-sdk", "//crates/tracedecay-session-memory:tracedecay-session-memory__d708e4dea92", "//crates/tracedecay-sessions:tracedecay-sessions", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__db430371074", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog", "//crates/tracedecay:tracedecay", ":build_script_build"], proc_macro_deps = all_crate_deps(proc_macro = True), aliases = aliases(normal = True), @@ -45,7 +45,7 @@ rust_binary( crate_root = "src/main.rs", edition = crate_edition(), compile_data = glob(["src/**/*"], exclude=["src/**/*.rs"], allow_empty = True), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True) + ["//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-integration:tracedecay-host-integration__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev", "//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", ":build_script_build"], proc_macro_deps = all_crate_deps(proc_macro = True), aliases = aliases(normal = True), @@ -58,7 +58,7 @@ rust_test( crate = ":tracedecay__test", crate_features = ["alloc-mimalloc", "default", "production", "test-transport"], edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-integration:tracedecay-host-integration__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev", "//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", ":build_script_build"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -74,7 +74,7 @@ rust_binary( crate_root = "build-support/host_cli_fixture.rs", edition = crate_edition(), compile_data = glob(["src/**/*"], exclude=["src/**/*.rs"], allow_empty = True), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-integration:tracedecay-host-integration__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev", "//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", ":build_script_build"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -87,7 +87,7 @@ rust_test( srcs = glob(["tests/**/*.rs"], exclude = ["tests/fixtures/**"]) + glob(["build-support/**/*.rs", "src/**/*.rs"]) + ["//crates/tracedecay:tests_common_sources", "//tests:support_sources"], crate_root = "tests/c_library_allocator.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-integration:tracedecay-host-integration__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev", "//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", ":build_script_build"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -104,7 +104,7 @@ rust_test( srcs = glob(["tests/core_cli_suite/**/*.rs"]) + glob(["build-support/**/*.rs", "tests/support/**/*.rs"]) + ["//crates/tracedecay:tests_common_sources", "//tests:support_sources"], crate_root = "tests/core_cli_suite/main.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-integration:tracedecay-host-integration__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev", "//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", ":build_script_build"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -121,7 +121,7 @@ rust_test( srcs = glob(["tests/host_journeys_suite/**/*.rs"]) + glob(["tests/support/**/*.rs"]) + ["//tests:support_sources"], crate_root = "tests/host_journeys_suite/main.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-integration:tracedecay-host-integration__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev", "//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", ":build_script_build"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -138,7 +138,7 @@ rust_test( srcs = glob(["tests/**/*.rs"], exclude = ["tests/fixtures/**"]) + glob(["build-support/**/*.rs", "src/**/*.rs"]) + ["//crates/tracedecay:tests_common_sources", "//tests:support_sources"], crate_root = "tests/process_allocator_heaps.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-integration:tracedecay-host-integration__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev", "//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", ":build_script_build"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -156,7 +156,7 @@ rust_test( srcs = glob(["tests/**/*.rs"], exclude = ["tests/fixtures/**"]) + glob(["build-support/**/*.rs", "src/**/*.rs"]) + ["//crates/tracedecay:tests_common_sources", "//tests:support_sources"], crate_root = "tests/refresh_memory_journey.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-integration:tracedecay-host-integration__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev", "//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", ":build_script_build"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -173,7 +173,7 @@ rust_test( srcs = glob(["tests/**/*.rs"], exclude = ["tests/fixtures/**"]) + glob(["build-support/**/*.rs", "src/**/*.rs"]) + ["//crates/tracedecay:tests_common_sources", "//tests:support_sources"], crate_root = "tests/retained_parse_heap.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-integration:tracedecay-host-integration__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev", "//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", ":build_script_build"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -190,7 +190,7 @@ rust_test( srcs = glob(["tests/**/*.rs"], exclude = ["tests/fixtures/**"]) + glob(["build-support/**/*.rs", "src/**/*.rs"]) + ["//crates/tracedecay:tests_common_sources", "//tests:support_sources"], crate_root = "tests/work_loop_journey.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-integration:tracedecay-host-integration__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev", "//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", ":build_script_build"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -207,7 +207,7 @@ rust_test( srcs = glob(["tests/**/*.rs"], exclude = ["tests/fixtures/**"]) + glob(["build-support/**/*.rs", "src/**/*.rs"]) + ["//crates/tracedecay:tests_common_sources", "//tests:support_sources"], crate_root = "tests/work_route_exposure_conformance.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-integration:tracedecay-host-integration__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev", "//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", ":build_script_build"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), diff --git a/crates/tracedecay-project/BUILD.bazel b/crates/tracedecay-project/BUILD.bazel index 85ec01f168..cedf1de6bd 100644 --- a/crates/tracedecay-project/BUILD.bazel +++ b/crates/tracedecay-project/BUILD.bazel @@ -16,7 +16,7 @@ rust_library( edition = crate_edition(), compile_data = glob(["src/**/*"], exclude=["src/**/*.rs"], allow_empty = True) + glob(["assets/**","fixtures/**","data/**","resources/**","vendor/**"], allow_empty = True) + ["//tests:fixtures_packaged_host_events_claude"], - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True) + ["//crates/tracedecay-agent-hosts:tracedecay-agent-hosts", "//crates/tracedecay-api:tracedecay-api", "//crates/tracedecay-application:tracedecay-application", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__d9fa2f52b76", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime", "//crates/tracedecay-code-index:tracedecay-code-index__bare__d455cac0e1d", "//crates/tracedecay-configuration:tracedecay-configuration__dad4b041aa0", "//crates/tracedecay-contracts:tracedecay-contracts", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api", "//crates/tracedecay-domain:tracedecay-domain", "//crates/tracedecay-global-db:tracedecay-global-db__d37f7709403", "//crates/tracedecay-graph-db:tracedecay-graph-db", "//crates/tracedecay-graph-query:tracedecay-graph-query__d0b53827a9a", "//crates/tracedecay-hooks:tracedecay-hooks", "//crates/tracedecay-host-admission:tracedecay-host-admission__d81b0b4f208", "//crates/tracedecay-lcm:tracedecay-lcm", "//crates/tracedecay-runtime-core:tracedecay-runtime-core", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime", "//crates/tracedecay-session-memory:tracedecay-session-memory__d43158f6601", "//crates/tracedecay-session-runtime:tracedecay-session-runtime", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__d4eabefc34b", "//crates/tracedecay-sessions:tracedecay-sessions", "//crates/tracedecay-source-edit:tracedecay-source-edit", "//crates/tracedecay-store-runtime:tracedecay-store-runtime", "//crates/tracedecay-store:tracedecay-store", "//crates/tracedecay-temporal-query:tracedecay-temporal-query", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog"], proc_macro_deps = all_crate_deps(proc_macro = True), aliases = aliases(normal = True), @@ -32,7 +32,7 @@ rust_library( edition = crate_edition(), compile_data = glob(["src/**/*"], exclude=["src/**/*.rs"], allow_empty = True) + glob(["assets/**","fixtures/**","data/**","resources/**","vendor/**"], allow_empty = True) + ["//tests:fixtures_packaged_host_events_claude"], - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True) + ["//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True), aliases = aliases(normal = True), @@ -48,7 +48,7 @@ rust_library( edition = crate_edition(), compile_data = glob(["src/**/*"], exclude=["src/**/*.rs"], allow_empty = True) + glob(["assets/**","fixtures/**","data/**","resources/**","vendor/**"], allow_empty = True) + ["//tests:fixtures_packaged_host_events_claude"], - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True) + ["//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+token-counting__d3efa111d08", "//crates/tracedecay-api:tracedecay-api", "//crates/tracedecay-application:tracedecay-application__d28025fc7f4", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__d6c8a9b65c3", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite__da9b78911ae", "//crates/tracedecay-code-index:tracedecay-code-index__-default_-medium__d6a7dfc4236", "//crates/tracedecay-configuration:tracedecay-configuration__d164684aea6", "//crates/tracedecay-contracts:tracedecay-contracts", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+token-counting__d46dac835a8", "//crates/tracedecay-domain:tracedecay-domain", "//crates/tracedecay-global-db:tracedecay-global-db__d1d92290ab9", "//crates/tracedecay-graph-db:tracedecay-graph-db", "//crates/tracedecay-graph-query:tracedecay-graph-query__d5f714e70ef", "//crates/tracedecay-hooks:tracedecay-hooks", "//crates/tracedecay-host-admission:tracedecay-host-admission__dc41fa61f2e", "//crates/tracedecay-lcm:tracedecay-lcm", "//crates/tracedecay-runtime-core:tracedecay-runtime-core", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime", "//crates/tracedecay-session-memory:tracedecay-session-memory__d708e4dea92", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__da9b7c59dcb", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__dc3c6d80f39", "//crates/tracedecay-sessions:tracedecay-sessions", "//crates/tracedecay-source-edit:tracedecay-source-edit__dbbea5e9843", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__db430371074", "//crates/tracedecay-store:tracedecay-store", "//crates/tracedecay-temporal-query:tracedecay-temporal-query", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog"], proc_macro_deps = all_crate_deps(proc_macro = True), aliases = aliases(normal = True), @@ -64,7 +64,7 @@ rust_library( edition = crate_edition(), compile_data = glob(["src/**/*"], exclude=["src/**/*.rs"], allow_empty = True) + glob(["assets/**","fixtures/**","data/**","resources/**","vendor/**"], allow_empty = True) + ["//tests:fixtures_packaged_host_events_claude"], - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True) + ["//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__d070e921b0e", "//crates/tracedecay-api:tracedecay-api", "//crates/tracedecay-application:tracedecay-application__d79d93e44ab", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__df7c1798e86", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__d8762ace120", "//crates/tracedecay-code-index:tracedecay-code-index__-default_-full_-medium__d480e0ce7ad", "//crates/tracedecay-configuration:tracedecay-configuration__d4582c40ab6", "//crates/tracedecay-contracts:tracedecay-contracts", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__de7045baddd", "//crates/tracedecay-domain:tracedecay-domain", "//crates/tracedecay-global-db:tracedecay-global-db__d59e53d4792", "//crates/tracedecay-graph-db:tracedecay-graph-db", "//crates/tracedecay-graph-query:tracedecay-graph-query__db88844d189", "//crates/tracedecay-hooks:tracedecay-hooks", "//crates/tracedecay-host-admission:tracedecay-host-admission__da13ef1915e", "//crates/tracedecay-lcm:tracedecay-lcm", "//crates/tracedecay-runtime-core:tracedecay-runtime-core", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime", "//crates/tracedecay-session-memory:tracedecay-session-memory__dc4cc807ff6", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__d2020b63d4c", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__d1e32f3aeb6", "//crates/tracedecay-sessions:tracedecay-sessions", "//crates/tracedecay-source-edit:tracedecay-source-edit__d46862a520f", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__d010928398b", "//crates/tracedecay-store:tracedecay-store", "//crates/tracedecay-temporal-query:tracedecay-temporal-query", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog"], proc_macro_deps = all_crate_deps(proc_macro = True), aliases = aliases(normal = True), @@ -77,7 +77,7 @@ rust_test( crate = ":tracedecay-project__+test-helpers_+test-transport__dev", crate_features = ["test-helpers", "test-transport"], edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), diff --git a/crates/tracedecay/BUILD.bazel b/crates/tracedecay/BUILD.bazel index 1bbfc4a2ad..f48d25f1f0 100644 --- a/crates/tracedecay/BUILD.bazel +++ b/crates/tracedecay/BUILD.bazel @@ -16,7 +16,7 @@ rust_library( edition = crate_edition(), compile_data = glob(["src/**/*"], exclude=["src/**/*.rs"], allow_empty = True) + glob(["assets/**","fixtures/**","data/**","resources/**","vendor/**"], allow_empty = True) + ["//crates/tracedecay-agent-hosts:src_agents_hermes_templates", "//tests:fixtures_provider_normalization_claude", "//tests:fixtures_provider_normalization_codex", "//tests:fixtures_provider_normalization_cursor", "//tests:fixtures_remote_tls"], - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True) + ["//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+token-counting__d3efa111d08", "//crates/tracedecay-api:tracedecay-api", "//crates/tracedecay-application:tracedecay-application__d28025fc7f4", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__d6c8a9b65c3", "//crates/tracedecay-automation:tracedecay-automation", "//crates/tracedecay-code-extraction:tracedecay-code-extraction", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__da2780f38c9", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite__da9b78911ae", "//crates/tracedecay-code-index:tracedecay-code-index__-default_-medium__d6a7dfc4236", "//crates/tracedecay-configuration:tracedecay-configuration__d164684aea6", "//crates/tracedecay-contracts:tracedecay-contracts", "//crates/tracedecay-daemon-control:tracedecay-daemon-control", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__dbf22c08471", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+token-counting__d46dac835a8", "//crates/tracedecay-domain:tracedecay-domain", "//crates/tracedecay-framing:tracedecay-framing", "//crates/tracedecay-global-db:tracedecay-global-db__d1d92290ab9", "//crates/tracedecay-graph-db:tracedecay-graph-db", "//crates/tracedecay-graph-query:tracedecay-graph-query__d5f714e70ef", "//crates/tracedecay-hooks:tracedecay-hooks", "//crates/tracedecay-host-admission:tracedecay-host-admission__dc41fa61f2e", "//crates/tracedecay-lcm:tracedecay-lcm", "//crates/tracedecay-lsp:tracedecay-lsp__da530592200", "//crates/tracedecay-maintenance:tracedecay-maintenance__dadd78a188f", "//crates/tracedecay-mcp:tracedecay-mcp__d835a4acdac", "//crates/tracedecay-policy:tracedecay-policy", "//crates/tracedecay-privacy:tracedecay-privacy", "//crates/tracedecay-private-fs:tracedecay-private-fs", "//crates/tracedecay-project:tracedecay-project__dca7a3b3082", "//crates/tracedecay-query:tracedecay-query__d773ffcfb02", "//crates/tracedecay-runtime-core:tracedecay-runtime-core", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime", "//crates/tracedecay-sdk:tracedecay-sdk", "//crates/tracedecay-session-memory:tracedecay-session-memory__d708e4dea92", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__da9b7c59dcb", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__dc3c6d80f39", "//crates/tracedecay-sessions:tracedecay-sessions", "//crates/tracedecay-source-edit:tracedecay-source-edit__dbbea5e9843", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__db430371074", "//crates/tracedecay-store:tracedecay-store", "//crates/tracedecay-temporal-query:tracedecay-temporal-query", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog"], proc_macro_deps = all_crate_deps(proc_macro = True), aliases = aliases(normal = True), @@ -32,7 +32,7 @@ rust_library( edition = crate_edition(), compile_data = glob(["src/**/*"], exclude=["src/**/*.rs"], allow_empty = True) + glob(["assets/**","fixtures/**","data/**","resources/**","vendor/**"], allow_empty = True) + ["//crates/tracedecay-agent-hosts:src_agents_hermes_templates", "//tests:fixtures_provider_normalization_claude", "//tests:fixtures_provider_normalization_codex", "//tests:fixtures_provider_normalization_cursor", "//tests:fixtures_remote_tls"], - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True) + ["//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation:tracedecay-automation__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__+test-helpers__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-policy:tracedecay-policy__dev", "//crates/tracedecay-privacy:tracedecay-privacy__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-search-eval:tracedecay-search-eval__+evaluator-corpus-languages_+lang-dockerfile_+lite__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True), aliases = aliases(normal = True), @@ -48,7 +48,7 @@ rust_library( edition = crate_edition(), compile_data = glob(["src/**/*"], exclude=["src/**/*.rs"], allow_empty = True) + glob(["assets/**","fixtures/**","data/**","resources/**","vendor/**"], allow_empty = True) + ["//crates/tracedecay-agent-hosts:src_agents_hermes_templates", "//tests:fixtures_provider_normalization_claude", "//tests:fixtures_provider_normalization_codex", "//tests:fixtures_provider_normalization_cursor", "//tests:fixtures_remote_tls"], - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True) + ["//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__d070e921b0e", "//crates/tracedecay-api:tracedecay-api", "//crates/tracedecay-application:tracedecay-application__d79d93e44ab", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__df7c1798e86", "//crates/tracedecay-automation:tracedecay-automation", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__cfg_2583ec52__d66eddaf54a", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__dc86514bcc6", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__d8762ace120", "//crates/tracedecay-code-index:tracedecay-code-index__-default_-full_-medium__d480e0ce7ad", "//crates/tracedecay-configuration:tracedecay-configuration__d4582c40ab6", "//crates/tracedecay-contracts:tracedecay-contracts", "//crates/tracedecay-daemon-control:tracedecay-daemon-control", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__d9d0e53a970", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__de7045baddd", "//crates/tracedecay-domain:tracedecay-domain", "//crates/tracedecay-framing:tracedecay-framing", "//crates/tracedecay-global-db:tracedecay-global-db__d59e53d4792", "//crates/tracedecay-graph-db:tracedecay-graph-db", "//crates/tracedecay-graph-query:tracedecay-graph-query__db88844d189", "//crates/tracedecay-hooks:tracedecay-hooks", "//crates/tracedecay-host-admission:tracedecay-host-admission__da13ef1915e", "//crates/tracedecay-lcm:tracedecay-lcm", "//crates/tracedecay-lsp:tracedecay-lsp", "//crates/tracedecay-maintenance:tracedecay-maintenance__db1f052cea7", "//crates/tracedecay-mcp:tracedecay-mcp", "//crates/tracedecay-policy:tracedecay-policy", "//crates/tracedecay-privacy:tracedecay-privacy", "//crates/tracedecay-private-fs:tracedecay-private-fs", "//crates/tracedecay-project:tracedecay-project__dde97d3b5f0", "//crates/tracedecay-query:tracedecay-query__dd0c74662a8", "//crates/tracedecay-runtime-core:tracedecay-runtime-core", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime", "//crates/tracedecay-sdk:tracedecay-sdk", "//crates/tracedecay-session-memory:tracedecay-session-memory__dc4cc807ff6", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__d2020b63d4c", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__d1e32f3aeb6", "//crates/tracedecay-sessions:tracedecay-sessions", "//crates/tracedecay-source-edit:tracedecay-source-edit__d46862a520f", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__d010928398b", "//crates/tracedecay-store:tracedecay-store", "//crates/tracedecay-temporal-query:tracedecay-temporal-query", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog"], proc_macro_deps = all_crate_deps(proc_macro = True), aliases = aliases(normal = True), @@ -62,7 +62,7 @@ rust_binary( crate_root = "examples/bench_extract.rs", edition = crate_edition(), compile_data = glob(["src/**/*"], exclude=["src/**/*.rs"], allow_empty = True), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", "//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation:tracedecay-automation__dev", "//crates/tracedecay-capture:tracedecay-capture__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__+test-helpers__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-policy:tracedecay-policy__dev", "//crates/tracedecay-privacy:tracedecay-privacy__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-search-eval:tracedecay-search-eval__+evaluator-corpus-languages_+lang-dockerfile_+lite__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tokenizer:tracedecay-tokenizer__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -75,7 +75,7 @@ rust_test( srcs = glob(["tests/agent_suite/**/*.rs"]) + glob(["tests/common/**/*.rs"]) + ["//tests:support_sources"], crate_root = "tests/agent_suite/main.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", "//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation:tracedecay-automation__dev", "//crates/tracedecay-capture:tracedecay-capture__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__+test-helpers__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-policy:tracedecay-policy__dev", "//crates/tracedecay-privacy:tracedecay-privacy__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-search-eval:tracedecay-search-eval__+evaluator-corpus-languages_+lang-dockerfile_+lite__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tokenizer:tracedecay-tokenizer__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -92,7 +92,7 @@ rust_test( srcs = glob(["tests/automation_runner_test/**/*.rs"]) + glob(["tests/common/**/*.rs"]) + ["//tests:support_sources"], crate_root = "tests/automation_runner_test/main.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", "//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation:tracedecay-automation__dev", "//crates/tracedecay-capture:tracedecay-capture__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__+test-helpers__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-policy:tracedecay-policy__dev", "//crates/tracedecay-privacy:tracedecay-privacy__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-search-eval:tracedecay-search-eval__+evaluator-corpus-languages_+lang-dockerfile_+lite__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tokenizer:tracedecay-tokenizer__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -109,7 +109,7 @@ rust_test( srcs = glob(["tests/claude_observation_benchmark/**/*.rs"]), crate_root = "tests/claude_observation_benchmark/main.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", "//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation:tracedecay-automation__dev", "//crates/tracedecay-capture:tracedecay-capture__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__+test-helpers__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-policy:tracedecay-policy__dev", "//crates/tracedecay-privacy:tracedecay-privacy__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-search-eval:tracedecay-search-eval__+evaluator-corpus-languages_+lang-dockerfile_+lite__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tokenizer:tracedecay-tokenizer__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -124,7 +124,7 @@ rust_test( srcs = glob(["tests/cursor_observation_identity_fallback/**/*.rs"]), crate_root = "tests/cursor_observation_identity_fallback/main.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", "//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation:tracedecay-automation__dev", "//crates/tracedecay-capture:tracedecay-capture__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__+test-helpers__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-policy:tracedecay-policy__dev", "//crates/tracedecay-privacy:tracedecay-privacy__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-search-eval:tracedecay-search-eval__+evaluator-corpus-languages_+lang-dockerfile_+lite__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tokenizer:tracedecay-tokenizer__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -139,7 +139,7 @@ rust_test( srcs = glob(["tests/daemon_suite/**/*.rs"]) + glob(["tests/common/**/*.rs"]) + ["//tests:support_sources"], crate_root = "tests/daemon_suite/main.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", "//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation:tracedecay-automation__dev", "//crates/tracedecay-capture:tracedecay-capture__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__+test-helpers__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-policy:tracedecay-policy__dev", "//crates/tracedecay-privacy:tracedecay-privacy__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-search-eval:tracedecay-search-eval__+evaluator-corpus-languages_+lang-dockerfile_+lite__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tokenizer:tracedecay-tokenizer__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -156,7 +156,7 @@ rust_test( srcs = glob(["tests/dashboard_api_test/**/*.rs"]) + glob(["tests/common/**/*.rs"]) + ["//tests:support_sources"], crate_root = "tests/dashboard_api_test/main.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", "//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation:tracedecay-automation__dev", "//crates/tracedecay-capture:tracedecay-capture__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__+test-helpers__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-policy:tracedecay-policy__dev", "//crates/tracedecay-privacy:tracedecay-privacy__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-search-eval:tracedecay-search-eval__+evaluator-corpus-languages_+lang-dockerfile_+lite__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tokenizer:tracedecay-tokenizer__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -173,7 +173,7 @@ rust_test( srcs = glob(["tests/graph_suite/**/*.rs"]) + glob(["tests/common/**/*.rs"]) + ["//tests:support_sources"], crate_root = "tests/graph_suite/main.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", "//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation:tracedecay-automation__dev", "//crates/tracedecay-capture:tracedecay-capture__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__+test-helpers__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-policy:tracedecay-policy__dev", "//crates/tracedecay-privacy:tracedecay-privacy__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-search-eval:tracedecay-search-eval__+evaluator-corpus-languages_+lang-dockerfile_+lite__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tokenizer:tracedecay-tokenizer__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -190,7 +190,7 @@ rust_test( srcs = glob(["tests/hermes_suite/**/*.rs"]) + glob(["tests/common/**/*.rs"]) + ["//tests:support_sources"], crate_root = "tests/hermes_suite/main.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", "//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation:tracedecay-automation__dev", "//crates/tracedecay-capture:tracedecay-capture__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__+test-helpers__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-policy:tracedecay-policy__dev", "//crates/tracedecay-privacy:tracedecay-privacy__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-search-eval:tracedecay-search-eval__+evaluator-corpus-languages_+lang-dockerfile_+lite__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tokenizer:tracedecay-tokenizer__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -207,7 +207,7 @@ rust_test( srcs = glob(["tests/hooks_lsp_suite/**/*.rs"]) + glob(["tests/common/**/*.rs"]) + ["//tests:support_sources"], crate_root = "tests/hooks_lsp_suite/main.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", "//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation:tracedecay-automation__dev", "//crates/tracedecay-capture:tracedecay-capture__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__+test-helpers__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-policy:tracedecay-policy__dev", "//crates/tracedecay-privacy:tracedecay-privacy__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-search-eval:tracedecay-search-eval__+evaluator-corpus-languages_+lang-dockerfile_+lite__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tokenizer:tracedecay-tokenizer__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -225,7 +225,7 @@ rust_test( srcs = glob(["tests/mcp_suite/**/*.rs"]) + glob(["tests/common/**/*.rs"]) + ["//tests:support_sources"], crate_root = "tests/mcp_suite/main.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", "//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation:tracedecay-automation__dev", "//crates/tracedecay-capture:tracedecay-capture__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__+test-helpers__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-policy:tracedecay-policy__dev", "//crates/tracedecay-privacy:tracedecay-privacy__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-search-eval:tracedecay-search-eval__+evaluator-corpus-languages_+lang-dockerfile_+lite__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tokenizer:tracedecay-tokenizer__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -242,7 +242,7 @@ rust_test( srcs = glob(["tests/memory_suite/**/*.rs"]) + glob(["tests/common/**/*.rs"]) + ["//tests:support_sources"], crate_root = "tests/memory_suite/main.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", "//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation:tracedecay-automation__dev", "//crates/tracedecay-capture:tracedecay-capture__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__+test-helpers__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-policy:tracedecay-policy__dev", "//crates/tracedecay-privacy:tracedecay-privacy__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-search-eval:tracedecay-search-eval__+evaluator-corpus-languages_+lang-dockerfile_+lite__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tokenizer:tracedecay-tokenizer__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -259,7 +259,7 @@ rust_test( srcs = glob(["tests/product_surface_suite/**/*.rs"]), crate_root = "tests/product_surface_suite/main.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", "//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation:tracedecay-automation__dev", "//crates/tracedecay-capture:tracedecay-capture__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__+test-helpers__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-policy:tracedecay-policy__dev", "//crates/tracedecay-privacy:tracedecay-privacy__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-search-eval:tracedecay-search-eval__+evaluator-corpus-languages_+lang-dockerfile_+lite__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tokenizer:tracedecay-tokenizer__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -275,7 +275,7 @@ rust_test( srcs = glob(["tests/runtime_acceptance_suite/**/*.rs"]) + glob(["tests/common/**/*.rs", "tests/session_suite/**/*.rs", "tests/session_suite/temporal_projection/**/*.rs", "tests/storage_suite/**/*.rs"]) + ["//crates/tracedecay-domain:tests_domain_suite_work_product_contract_sources", "//crates/tracedecay-domain:tests_sources", "//tests:support_sources"], crate_root = "tests/runtime_acceptance_suite/main.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", "//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation:tracedecay-automation__dev", "//crates/tracedecay-capture:tracedecay-capture__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__+test-helpers__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-policy:tracedecay-policy__dev", "//crates/tracedecay-privacy:tracedecay-privacy__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-search-eval:tracedecay-search-eval__+evaluator-corpus-languages_+lang-dockerfile_+lite__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tokenizer:tracedecay-tokenizer__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -292,7 +292,7 @@ rust_test( srcs = glob(["tests/session_suite/**/*.rs"]) + glob(["tests/common/**/*.rs"]) + ["//tests:support_sources"], crate_root = "tests/session_suite/main.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", "//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation:tracedecay-automation__dev", "//crates/tracedecay-capture:tracedecay-capture__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__+test-helpers__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-policy:tracedecay-policy__dev", "//crates/tracedecay-privacy:tracedecay-privacy__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-search-eval:tracedecay-search-eval__+evaluator-corpus-languages_+lang-dockerfile_+lite__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tokenizer:tracedecay-tokenizer__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -309,7 +309,7 @@ rust_test( srcs = ["//tests:storage_runtime_rusqlite_suite_sources"], crate_root = "//tests:storage_runtime_rusqlite_suite/main.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", "//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation:tracedecay-automation__dev", "//crates/tracedecay-capture:tracedecay-capture__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__+test-helpers__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-policy:tracedecay-policy__dev", "//crates/tracedecay-privacy:tracedecay-privacy__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-search-eval:tracedecay-search-eval__+evaluator-corpus-languages_+lang-dockerfile_+lite__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tokenizer:tracedecay-tokenizer__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -324,7 +324,7 @@ rust_test( srcs = glob(["tests/storage_suite/**/*.rs"]) + glob(["tests/common/**/*.rs"]) + ["//tests:support_sources"], crate_root = "tests/storage_suite/main.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", "//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation:tracedecay-automation__dev", "//crates/tracedecay-capture:tracedecay-capture__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__+test-helpers__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-policy:tracedecay-policy__dev", "//crates/tracedecay-privacy:tracedecay-privacy__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-search-eval:tracedecay-search-eval__+evaluator-corpus-languages_+lang-dockerfile_+lite__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tokenizer:tracedecay-tokenizer__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -341,7 +341,7 @@ rust_test( srcs = glob(["tests/transcript_ingest_suite/**/*.rs"]) + glob(["tests/common/**/*.rs"]) + ["//tests:support_sources"], crate_root = "tests/transcript_ingest_suite/main.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", "//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation:tracedecay-automation__dev", "//crates/tracedecay-capture:tracedecay-capture__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__+test-helpers__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-policy:tracedecay-policy__dev", "//crates/tracedecay-privacy:tracedecay-privacy__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-search-eval:tracedecay-search-eval__+evaluator-corpus-languages_+lang-dockerfile_+lite__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tokenizer:tracedecay-tokenizer__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -358,7 +358,7 @@ rust_test( srcs = glob(["tests/transport_acceptance_suite/**/*.rs"]) + glob(["tests/common/**/*.rs"]) + ["//tests:support_sources"], crate_root = "tests/transport_acceptance_suite/main.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", "//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation:tracedecay-automation__dev", "//crates/tracedecay-capture:tracedecay-capture__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__+test-helpers__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-policy:tracedecay-policy__dev", "//crates/tracedecay-privacy:tracedecay-privacy__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-search-eval:tracedecay-search-eval__+evaluator-corpus-languages_+lang-dockerfile_+lite__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tokenizer:tracedecay-tokenizer__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -377,7 +377,7 @@ rust_test( srcs = glob(["benches/**/*.rs"]), crate_root = "benches/large_repos.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", "//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation:tracedecay-automation__dev", "//crates/tracedecay-capture:tracedecay-capture__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__+test-helpers__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-policy:tracedecay-policy__dev", "//crates/tracedecay-privacy:tracedecay-privacy__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-search-eval:tracedecay-search-eval__+evaluator-corpus-languages_+lang-dockerfile_+lite__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tokenizer:tracedecay-tokenizer__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -394,7 +394,7 @@ rust_test( srcs = glob(["benches/**/*.rs"]), crate_root = "benches/session_temporal.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", "//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation:tracedecay-automation__dev", "//crates/tracedecay-capture:tracedecay-capture__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__+test-helpers__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-policy:tracedecay-policy__dev", "//crates/tracedecay-privacy:tracedecay-privacy__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-search-eval:tracedecay-search-eval__+evaluator-corpus-languages_+lang-dockerfile_+lite__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tokenizer:tracedecay-tokenizer__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -411,7 +411,7 @@ rust_test( srcs = glob(["benches/**/*.rs"]), crate_root = "benches/transcript_ingest.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", "//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation:tracedecay-automation__dev", "//crates/tracedecay-capture:tracedecay-capture__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__+test-helpers__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-policy:tracedecay-policy__dev", "//crates/tracedecay-privacy:tracedecay-privacy__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-search-eval:tracedecay-search-eval__+evaluator-corpus-languages_+lang-dockerfile_+lite__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tokenizer:tracedecay-tokenizer__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -428,7 +428,7 @@ rust_test( srcs = glob(["benches/**/*.rs"]), crate_root = "benches/rmcp_connection_pipeline.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", "//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation:tracedecay-automation__dev", "//crates/tracedecay-capture:tracedecay-capture__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__+test-helpers__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-policy:tracedecay-policy__dev", "//crates/tracedecay-privacy:tracedecay-privacy__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-search-eval:tracedecay-search-eval__+evaluator-corpus-languages_+lang-dockerfile_+lite__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tokenizer:tracedecay-tokenizer__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -445,7 +445,7 @@ rust_test( srcs = glob(["benches/**/*.rs"]), crate_root = "benches/mcp_server_construction.rs", edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay:tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", "//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation:tracedecay-automation__dev", "//crates/tracedecay-capture:tracedecay-capture__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__+test-helpers__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-policy:tracedecay-policy__dev", "//crates/tracedecay-privacy:tracedecay-privacy__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-search-eval:tracedecay-search-eval__+evaluator-corpus-languages_+lang-dockerfile_+lite__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tokenizer:tracedecay-tokenizer__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), @@ -467,7 +467,7 @@ rust_test( crate = ":tracedecay__+rmcp-benchmark_+test-helpers_+test-transport__dev", crate_features = ["default", "full", "lite", "production", "rmcp-benchmark", "test-helpers", "test-transport", "token-counting"], edition = crate_edition(), - version = "1.0.0-beta.92", + version = "1.0.0-beta.93", deps = all_crate_deps(normal = True, normal_dev = True) + ["//crates/tracedecay-agent-hosts:tracedecay-agent-hosts__+test-transport_+token-counting__dev", "//crates/tracedecay-api:tracedecay-api__dev", "//crates/tracedecay-application:tracedecay-application__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation-runtime:tracedecay-automation-runtime__+test-helpers_+test-transport__dev", "//crates/tracedecay-automation:tracedecay-automation__dev", "//crates/tracedecay-capture:tracedecay-capture__dev", "//crates/tracedecay-code-extraction:tracedecay-code-extraction__+test-helpers__dev", "//crates/tracedecay-code-index-retention:tracedecay-code-index-retention__+test-helpers__dev", "//crates/tracedecay-code-index-runtime:tracedecay-code-index-runtime__+full_+lite_+test-helpers_+test-transport__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-configuration:tracedecay-configuration__+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-daemon-control:tracedecay-daemon-control__dev", "//crates/tracedecay-daemon-identity:tracedecay-daemon-identity__dev", "//crates/tracedecay-daemon-protocol:tracedecay-daemon-protocol__+test-helpers__dev", "//crates/tracedecay-daemon-service:tracedecay-daemon-service__+test-helpers__dev", "//crates/tracedecay-dashboard-api:tracedecay-dashboard-api__+test-transport_+token-counting__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-framing:tracedecay-framing__dev", "//crates/tracedecay-global-db:tracedecay-global-db__+test-helpers__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-graph-query:tracedecay-graph-query__+test-helpers__dev", "//crates/tracedecay-hooks:tracedecay-hooks__dev", "//crates/tracedecay-host-admission:tracedecay-host-admission__+test-helpers_+test-transport__dev", "//crates/tracedecay-lcm:tracedecay-lcm__+test-helpers__dev", "//crates/tracedecay-lsp:tracedecay-lsp__dev", "//crates/tracedecay-maintenance:tracedecay-maintenance__+test-helpers__dev", "//crates/tracedecay-mcp:tracedecay-mcp__+test-helpers_+test-transport__dev", "//crates/tracedecay-policy:tracedecay-policy__dev", "//crates/tracedecay-privacy:tracedecay-privacy__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-project:tracedecay-project__+test-helpers_+test-transport__dev", "//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-rusqlite-runtime:tracedecay-rusqlite-runtime__+test-runtime_+test-transport__dev", "//crates/tracedecay-sdk:tracedecay-sdk__dev", "//crates/tracedecay-search-eval:tracedecay-search-eval__+evaluator-corpus-languages_+lang-dockerfile_+lite__dev", "//crates/tracedecay-session-memory:tracedecay-session-memory__+test-transport__dev", "//crates/tracedecay-session-runtime:tracedecay-session-runtime__+test-helpers__dev", "//crates/tracedecay-session-temporal-store:tracedecay-session-temporal-store__+test-helpers_+test-transport__dev", "//crates/tracedecay-sessions:tracedecay-sessions__+test-helpers__dev", "//crates/tracedecay-source-edit:tracedecay-source-edit__dev", "//crates/tracedecay-store-runtime:tracedecay-store-runtime__+test-helpers__dev", "//crates/tracedecay-store:tracedecay-store__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev", "//crates/tracedecay-tokenizer:tracedecay-tokenizer__dev", "//crates/tracedecay-tool-catalog:tracedecay-tool-catalog__dev"], proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), From 6b5a9924da4f8c818680dcb60699f4af52d421c9 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Mon, 26 Oct 2026 08:57:56 +0000 Subject: [PATCH 3/8] fix(privacy): protect YAML keys and BOM-prefixed documents Restack unique #4527 onto the rewritten #4485 tip. --- .../tracedecay-privacy/src/structural_id.rs | 36 ++- crates/tracedecay-privacy/src/structured.rs | 3 +- .../src/structured_tests.rs | 47 +++- .../tracedecay-privacy/src/structured_text.rs | 47 +++- .../src/structured_text_tests.rs | 224 ++++++++++++++++++ 5 files changed, 342 insertions(+), 15 deletions(-) diff --git a/crates/tracedecay-privacy/src/structural_id.rs b/crates/tracedecay-privacy/src/structural_id.rs index b11a740a86..5d9397c4ad 100644 --- a/crates/tracedecay-privacy/src/structural_id.rs +++ b/crates/tracedecay-privacy/src/structural_id.rs @@ -1,7 +1,7 @@ use tracedecay_domain::canonical_text::is_tagged_lowercase_hex; use super::length_prefixed_sha256_hex; -use super::structured_text::sanitize_provider_metadata_text; +use super::structured_text::sanitize_structured_text; const PROTECTION_DOMAIN_V1: &[u8] = b"tracedecay.structural-identity-protection.v1"; const PROTECTION_PREFIX_V1: &str = "privacy.structural-id.v1."; @@ -28,8 +28,13 @@ pub fn protect_sensitive_structural_id(value: &str) -> Result sanitize_parsed(value, limits), Err(JsonPreflightFailureV1::Malformed) => sanitize_malformed(text, limits), // The preflight refuses before `Value` materializes, so it is the only diff --git a/crates/tracedecay-privacy/src/structured_tests.rs b/crates/tracedecay-privacy/src/structured_tests.rs index c6dff8a23a..c8589712b8 100644 --- a/crates/tracedecay-privacy/src/structured_tests.rs +++ b/crates/tracedecay-privacy/src/structured_tests.rs @@ -1,5 +1,6 @@ use super::structured::{ - StructuredSanitizationError, StructuredSanitizationLimits, sanitize_structured_payload, + StructuredSanitizationError, StructuredSanitizationLimits, sanitize_provider_metadata_json, + sanitize_structured_payload, }; const SECRET: &str = "sk-test-123456789012345678901234"; @@ -91,6 +92,50 @@ fn structured_limits_deny_raw_expansion_depth_and_item_overruns() { ); } +#[test] +fn bom_json_parsing_preserves_raw_byte_limits_and_metadata_redaction() { + let raw = r#"{"safe":"kept"}"#; + let with_bom = format!("\u{feff}{raw}"); + let plain_limits = + StructuredSanitizationLimits::new(raw.len(), 128, 8, 8).expect("valid limits"); + let plain = sanitize_structured_payload(raw.as_bytes(), plain_limits) + .expect("unprefixed input fits its exact byte allowance"); + assert!(plain.was_structurally_parsed()); + assert_eq!( + sanitize_structured_payload(with_bom.as_bytes(), plain_limits).unwrap_err(), + StructuredSanitizationError::RawBytesExceeded, + "the BOM's three original bytes still count toward raw admission" + ); + + let bom_limits = + StructuredSanitizationLimits::new(with_bom.len(), 128, 8, 8).expect("valid limits"); + let prefixed = sanitize_structured_payload(with_bom.as_bytes(), bom_limits) + .expect("BOM input fits its exact byte allowance"); + assert!(prefixed.was_structurally_parsed()); + assert_eq!(prefixed.payload(), plain.payload()); + assert_eq!( + sanitize_provider_metadata_json(&with_bom, raw.len() as u64), + None + ); + assert_eq!( + sanitize_provider_metadata_json(&with_bom, with_bom.len() as u64).as_ref(), + Some(plain.payload()) + ); + + let private_metadata = "\u{feff}{\"vault_passphrase\":\"ordinary-value\",\"safe\":\"kept\"}"; + assert_eq!( + sanitize_provider_metadata_json(private_metadata, 4096), + Some(serde_json::json!({ + "vault_passphrase": "[TraceDecay redacted: sensitive field]", + "safe": "kept" + })) + ); + assert_eq!( + sanitize_structured_payload(b"\xef\xbb\xbf{\"key\":1,\"key\":2}", limits()).unwrap_err(), + StructuredSanitizationError::UnsafeJsonStructure + ); +} + /// Pins the format a table-headed document is classified as, separately from /// what the sanitizer then does with it. The sanitizer reports "no format" both /// when nothing claimed the document and when it was quarantined, so a failure diff --git a/crates/tracedecay-privacy/src/structured_text.rs b/crates/tracedecay-privacy/src/structured_text.rs index 60cb97d8e8..109fd1fa31 100644 --- a/crates/tracedecay-privacy/src/structured_text.rs +++ b/crates/tracedecay-privacy/src/structured_text.rs @@ -41,12 +41,15 @@ use super::detector_kernel::{NormalizedSensitiveKey, SensitiveKeyPolicy}; use super::length_prefixed_sha256_hex; use super::rules::{CredentialPatternSet, CredentialScanBatchV1}; use super::structured::{ - ParsedStructuredTextV1, StructuredSanitizationError, StructuredSanitizationLimits, - StructuredTextFieldV1, StructuredTextFormatV1, StructuredTextParseFailureV1, - parse_structured_text, sanitize_structured_payload, validate_structured_text_limits, + MAX_STRUCTURED_TEXT_BYTES, ParsedStructuredTextV1, StructuredSanitizationError, + StructuredSanitizationLimits, StructuredTextFieldV1, StructuredTextFormatV1, + StructuredTextParseFailureV1, parse_structured_text, sanitize_structured_payload, + validate_structured_text_limits, }; -pub const CODE_SOURCE_SANITIZER_VERSION_V1: &str = "privacy.code-source.v1"; +// Retained generations must not reuse content admitted before key and BOM +// inspection. The receipt shape and identity domain remain V1. +pub const CODE_SOURCE_SANITIZER_VERSION_V1: &str = "privacy.code-source.v1.structured-keys.1"; const CODE_SOURCE_RECEIPT_DOMAIN_V1: &[u8] = b"tracedecay.privacy.code-source.receipt.v1\0"; pub const LCM_PAYLOAD_SANITIZER_VERSION_V1: &str = "privacy.lcm-payload.v1"; const LCM_PAYLOAD_RECEIPT_DOMAIN_V1: &[u8] = b"tracedecay.privacy.lcm-payload.receipt.v1\0"; @@ -171,7 +174,16 @@ pub(crate) fn sanitize_structured_text( raw: &str, ) -> Result { let patterns = credential_patterns()?; - let sanitized = sanitize_structured_text_with(raw, patterns)?; + if raw.len() > MAX_STRUCTURED_TEXT_BYTES { + return Err(DetectionError::ScanLimitExceeded); + } + // Parsing, span discovery, and rewrite verification must use the same + // coordinates. Restore the BOM only after those operations finish. + let document = raw.strip_prefix('\u{feff}').unwrap_or(raw); + let mut sanitized = sanitize_structured_text_with(document, patterns)?; + if document.len() != raw.len() { + sanitized.sanitized_text.insert(0, '\u{feff}'); + } patterns .checked(sanitized) .map_err(|_| DetectionError::Initialization) @@ -202,7 +214,13 @@ fn sanitize_structured_text_with( tree_candidates(raw, &parsed, &policy, patterns, &mut quarantine_findings) } else { ( - line_candidates(raw, &parsed.fields, &policy, patterns), + line_candidates( + raw, + &parsed.fields, + &policy, + patterns, + &mut quarantine_findings, + ), RedactedKeys::default(), ) }; @@ -406,9 +424,18 @@ fn line_candidates( fields: &[StructuredTextFieldV1], policy: &ConfiguredSensitiveKeyPolicy<'_>, patterns: &CredentialPatternSet, + quarantine_findings: &mut Vec, ) -> Vec { let mut candidates = Vec::new(); for field in fields { + let mut key_evidence = field.key.clone(); + redact_text( + &mut key_evidence, + "$", + patterns, + quarantine_findings, + SanitizationActionV1::Quarantined, + ); if field.value_span.start >= field.value_span.end || field.value_span.end > raw.len() || !raw.is_char_boundary(field.value_span.start) @@ -1174,9 +1201,9 @@ pub fn sanitize_code_source_bytes( /// detector change must invalidate a completed-rescan watermark. pub fn lcm_payload_detector_revision() -> &'static str { // Advance this input when detector semantics change independently of the - // rule documents. Restored strict entropy must recheck previously exempt - // compound tokens without changing the receipt contract. - const ALGORITHM_REVISION: &[u8] = b"strict-entropy.1"; + // rule documents. Key and BOM inspection must recheck payloads admitted + // by the prior implementation without changing the receipt contract. + const ALGORITHM_REVISION: &[u8] = b"strict-entropy.1+structured-keys.1"; static REVISION: OnceLock = OnceLock::new(); REVISION.get_or_init(|| { let [catalogue, supplement] = super::rules::rule_document_bytes(); @@ -1262,7 +1289,7 @@ fn detect_lcm_payload(raw: &str) -> Result<(String, Vec), if raw.len() > MAX_LCM_PAYLOAD_BYTES_V1 { return Err(DetectionError::ScanLimitExceeded); } - let trimmed = raw.trim_start(); + let trimmed = raw.strip_prefix('\u{feff}').unwrap_or(raw).trim_start(); let json_container = trimmed.starts_with('{') || trimmed .strip_prefix('[') diff --git a/crates/tracedecay-privacy/src/structured_text_tests.rs b/crates/tracedecay-privacy/src/structured_text_tests.rs index cbb28610fc..1b30d64234 100644 --- a/crates/tracedecay-privacy/src/structured_text_tests.rs +++ b/crates/tracedecay-privacy/src/structured_text_tests.rs @@ -506,6 +506,230 @@ fn lcm_json_credential_bearing_keys_quarantine_instead_of_faulting_the_receipt() ); } +fn assert_public_credential_key_protection(raw: &str, credential_key: &str) { + assert_eq!(raw_sweep(PLACEHOLDER), PLACEHOLDER); + assert!(raw_sweep(raw).contains(PLACEHOLDER)); + assert!(!raw_sweep(credential_key).contains(credential_key)); + assert!( + sanitize_structured_text(raw) + .expect("valid structured document is scanned") + .format() + .is_some(), + "a leading BOM must not bypass structural parsing" + ); + + let assert_safe_output = |text: &str| { + assert!(!text.contains(credential_key), "credential key was exposed"); + assert!(!text.contains(PLACEHOLDER), "the key's value was exposed"); + assert!(text.contains("us-east"), "unrelated field was discarded"); + }; + let assert_safe_evidence = |evidence: &str| { + assert!(!evidence.contains(credential_key)); + assert!(!evidence.contains(PLACEHOLDER)); + }; + let assert_key_refusal = |error: DetectionError| { + assert_eq!(error, DetectionError::CredentialKeyQuarantine); + assert_safe_evidence(&error.to_string()); + }; + + match sanitize_code_source_bytes(raw.as_bytes(), CodeSourceShapeV1::StructuredData) { + Ok(sanitized) => { + let (bytes, receipt) = sanitized.into_parts(); + let text = String::from_utf8(bytes).expect("sanitized UTF-8"); + assert_safe_output(&text); + assert_safe_evidence(&serde_json::to_string(&receipt).expect("source receipt")); + let replayed = + sanitize_code_source_bytes(text.as_bytes(), CodeSourceShapeV1::StructuredData) + .expect("redacted source remains usable"); + assert_eq!(replayed.sanitized_bytes(), text.as_bytes()); + } + Err(error) => assert_key_refusal(error), + } + + match sanitize_lcm_payload_text(raw) { + Ok(sanitized) => { + let (text, receipt, findings) = sanitized.into_parts(); + assert_safe_output(&text); + assert_safe_evidence( + &serde_json::to_string(&(receipt, findings)).expect("LCM evidence"), + ); + let replayed = sanitize_lcm_payload_text(&text).expect("redacted LCM stays usable"); + assert_eq!(replayed.sanitized_text(), text); + } + Err(error) => assert_key_refusal(error), + } + + if let Some(text) = sanitize_provider_metadata_text(raw) { + assert_safe_output(&text); + assert_eq!( + sanitize_provider_metadata_text(&text).as_deref(), + Some(text.as_str()), + "redacted metadata must be a fixed point" + ); + } +} + +#[test] +fn yaml_credential_keys_protect_plain_descendants_through_public_sanitizers() { + let credential_key = ["sk", "-test-", "1234567890abcdef"].concat(); + const ALPHABET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; + let entropy_key: String = (0..48) + .map(|index| char::from(ALPHABET[(index * 17) % ALPHABET.len()])) + .collect(); + for (key, raw) in [ + // This also has valid HTTP-header syntax; that route must protect keys. + ( + credential_key.as_str(), + format!("{credential_key}: {PLACEHOLDER}\nregion: us-east\n"), + ), + ( + entropy_key.as_str(), + format!("{entropy_key}: {PLACEHOLDER}\nregion: us-east\n"), + ), + ( + credential_key.as_str(), + format!( + "provider:\n {credential_key}:\n accounts:\n - {PLACEHOLDER}\nregion: us-east\n" + ), + ), + ] { + assert_public_credential_key_protection(&raw, key); + } +} + +#[test] +fn empty_credential_key_fields_still_require_key_quarantine() { + let credential_key = ["sk", "-test-", "1234567890abcdef"].concat(); + let raw = format!("{credential_key}:\nregion: us-east\n"); + + assert_eq!( + sanitize_code_source_bytes(raw.as_bytes(), CodeSourceShapeV1::StructuredData) + .map(|_| ()) + .expect_err("empty value does not make its credential key safe"), + DetectionError::CredentialKeyQuarantine + ); + assert_eq!( + sanitize_lcm_payload_text(&raw).expect_err("LCM withholds credential key"), + DetectionError::CredentialKeyQuarantine + ); + assert!(sanitize_provider_metadata_text(&raw).is_none()); +} + +#[test] +fn bom_credential_keys_protect_plain_descendants_in_json_and_toml() { + let credential_key = ["sk", "-test-", "1234567890abcdef"].concat(); + for raw in [ + format!( + "\u{feff}{{\"{credential_key}\":{{\"accounts\":[\"{PLACEHOLDER}\"]}},\"region\":\"us-east\"}}" + ), + format!( + "\u{feff}region = \"us-east\"\n[{credential_key}]\naccounts = [\"{PLACEHOLDER}\"]\n" + ), + ] { + assert_public_credential_key_protection(&raw, &credential_key); + } +} + +#[test] +fn bom_sensitive_fields_keep_exact_source_offsets_and_neighbors() { + for (format, raw, expected) in [ + ( + StructuredTextFormatV1::Json, + format!( + "\u{feff}{{\"note\":\"café\", \"vault_passphrase\":\"{PLACEHOLDER}\", \"region\":\"us-east\"}}\n" + ), + "\u{feff}{\"note\":\"café\", \"vault_passphrase\":\"TraceDecay-redacted-sensitive-field\", \"region\":\"us-east\"}\n", + ), + ( + StructuredTextFormatV1::Toml, + format!( + "\u{feff}# café\n[vault]\nregion = \"us-east\"\nvault_passphrase = \"{PLACEHOLDER}\" # rotate\n" + ), + "\u{feff}# café\n[vault]\nregion = \"us-east\"\nvault_passphrase = \"TraceDecay-redacted-sensitive-field\" # rotate\n", + ), + ] { + assert_detected_only_by_parsing(&raw, format, expected); + let source = sanitize_code_source_bytes(raw.as_bytes(), CodeSourceShapeV1::StructuredData) + .expect("BOM source sanitizes"); + assert_eq!(source.sanitized_bytes(), expected.as_bytes()); + assert_eq!( + sanitize_provider_metadata_text(&raw).as_deref(), + Some(expected) + ); + let lcm = sanitize_lcm_payload_text(&raw).expect("BOM payload sanitizes"); + assert!(!lcm.sanitized_text().contains(PLACEHOLDER)); + assert!(lcm.sanitized_text().contains("us-east")); + } +} + +#[test] +fn bom_ordinary_structured_documents_preserve_nonsecret_content() { + for raw in [ + "\u{feff}{\"note\":\"café\", \"region\":\"us-east\"}\n", + "\u{feff}# café\n[service]\nregion = \"us-east\"\n", + "region: us-east\ncomponent: worker\n", + ] { + let source = sanitize_code_source_bytes(raw.as_bytes(), CodeSourceShapeV1::StructuredData) + .expect("ordinary source sanitizes"); + assert_eq!(source.sanitized_bytes(), raw.as_bytes()); + assert_eq!(sanitize_provider_metadata_text(raw).as_deref(), Some(raw)); + let lcm = sanitize_lcm_payload_text(raw).expect("ordinary LCM payload sanitizes"); + assert!(lcm.sanitized_text().contains("us-east")); + assert!(lcm.findings().is_empty()); + } +} + +#[test] +fn bom_malformed_structured_documents_cannot_fall_back_to_raw_scanning() { + for raw in [ + format!("\u{feff}{{\"vault_passphrase\":\"{PLACEHOLDER}\",\"broken\":["), + format!("\u{feff}[vault]\nvault_passphrase = \"{PLACEHOLDER}\"\nbroken = [\n"), + format!( + "\u{feff}{{\"vault_passphrase\":\"{PLACEHOLDER}\",\"vault_passphrase\":\"safe-replacement\"}}" + ), + ] { + assert!(raw_sweep(&raw).contains(PLACEHOLDER)); + assert_eq!( + sanitize_code_source_bytes(raw.as_bytes(), CodeSourceShapeV1::StructuredData) + .map(|_| ()) + .expect_err("malformed BOM source is withheld"), + DetectionError::StructuredQuarantine + ); + assert_eq!( + sanitize_lcm_payload_text(&raw).expect_err("malformed BOM payload is withheld"), + DetectionError::StructuredQuarantine + ); + assert!(sanitize_provider_metadata_text(&raw).is_none()); + } +} + +#[test] +fn bom_lcm_json_keeps_its_existing_budget_and_original_input_receipt() { + // JSON payloads already have a larger LCM allowance than general structured + // text. A BOM must not send valid JSON through the smaller text route. + let raw = format!( + "{{\"text\":\"{}\",\"region\":\"us-east\"}}", + "a".repeat(1_048_576) + ); + let with_bom = format!("\u{feff}{raw}"); + let (plain_text, plain_receipt, plain_findings) = sanitize_lcm_payload_text(&raw) + .expect("JSON fits the existing LCM payload allowance") + .into_parts(); + let (bom_text, bom_receipt, bom_findings) = sanitize_lcm_payload_text(&with_bom) + .expect("BOM does not change the JSON allowance") + .into_parts(); + + assert_eq!(bom_text, plain_text); + assert_eq!(bom_findings, plain_findings); + assert!(bom_findings.is_empty()); + assert_eq!(bom_receipt.payload(), plain_receipt.payload()); + assert_ne!( + bom_receipt.receipt(), + plain_receipt.receipt(), + "receipt identity must retain the original input's BOM bytes" + ); +} + #[test] fn prose_opening_with_a_bracketed_annotation_line_is_not_toml_quarantine() { // LCM compaction emits scaffold messages such as From fbb57b00b57ae046b89b56b698856d8982da04b9 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Mon, 26 Oct 2026 08:58:01 +0000 Subject: [PATCH 4/8] fix(config): retire unused sync controls Restack unique #4528 onto the rewritten #4527 tip. --- .../src/config/mod.rs | 52 ++++- .../src/config/model.rs | 6 - .../src/configuration/operations.rs | 117 +++++++++- crates/tracedecay-domain/src/configuration.rs | 8 +- crates/tracedecay-domain/src/lib.rs | 3 +- .../src/configuration/registry.rs | 17 -- .../src/configuration/store/tests/mod.rs | 1 + .../configuration/store/tests/retired_sync.rs | 221 ++++++++++++++++++ 8 files changed, 387 insertions(+), 38 deletions(-) create mode 100644 crates/tracedecay-global-db/src/configuration/store/tests/retired_sync.rs diff --git a/crates/tracedecay-configuration/src/config/mod.rs b/crates/tracedecay-configuration/src/config/mod.rs index 77b2c79384..33771069b2 100644 --- a/crates/tracedecay-configuration/src/config/mod.rs +++ b/crates/tracedecay-configuration/src/config/mod.rs @@ -25,8 +25,7 @@ use tracedecay_domain::configuration::{ LcmSummarizerExecutablesV1, SYNC_AUTO_INIT_SETTING_KEY, SYNC_AUTO_TRACK_PR_BRANCHES_SETTING_KEY, SYNC_AUTO_TRACK_PR_POLL_SECS_SETTING_KEY, SYNC_AUTO_WATCH_SETTING_KEY, SYNC_BACKSTOP_INTERVAL_MINS_SETTING_KEY, - SYNC_BRANCH_GC_DAYS_SETTING_KEY, SYNC_FULL_SYNC_ESCALATION_FILES_SETTING_KEY, - SYNC_MAX_CONCURRENT_SYNCS_SETTING_KEY, SYNC_READ_COOLDOWN_SECS_SETTING_KEY, + SYNC_BRANCH_GC_DAYS_SETTING_KEY, SYNC_READ_COOLDOWN_SECS_SETTING_KEY, SYNC_READ_REFRESH_SETTING_KEY, SYNC_SESSION_START_STALE_THRESHOLD_SECS_SETTING_KEY, SYNC_SESSION_START_SYNC_SETTING_KEY, SYNC_WATCH_DEBOUNCE_MS_SETTING_KEY, SYNC_WATCH_LINKED_WORKTREES_SETTING_KEY, SYNC_WATCH_MAX_DELAY_MS_SETTING_KEY, @@ -284,11 +283,6 @@ fn runtime_config_from_snapshot( snapshot, SYNC_BACKSTOP_INTERVAL_MINS_SETTING_KEY, )?, - full_sync_escalation_files: required_usize( - snapshot, - SYNC_FULL_SYNC_ESCALATION_FILES_SETTING_KEY, - )?, - max_concurrent_syncs: required_usize(snapshot, SYNC_MAX_CONCURRENT_SYNCS_SETTING_KEY)?, branch_gc_days: required_unsigned(snapshot, SYNC_BRANCH_GC_DAYS_SETTING_KEY)?, auto_init: required_bool(snapshot, SYNC_AUTO_INIT_SETTING_KEY)?, auto_track_pr_branches: required_bool( @@ -458,7 +452,8 @@ mod tests { use tracedecay_domain::configuration::{ ConfigurationLayerIdV1, ConfigurationRevisionId, ConfigurationSnapshotV1, ConfigurationValueV1, INDEX_EXCLUDE_SETTING_KEY, INDEX_MAX_FILE_SIZE_SETTING_KEY, - SYNC_WATCH_DEBOUNCE_MS_SETTING_KEY, SettingKey, + SYNC_READ_COOLDOWN_SECS_SETTING_KEY, SYNC_WATCH_DEBOUNCE_MS_SETTING_KEY, + SYNC_WATCH_LINKED_WORKTREES_SETTING_KEY, SYNC_WATCH_MAX_PROJECTS_SETTING_KEY, SettingKey, }; use tracedecay_domain::errors::TraceDecayError; @@ -546,6 +541,47 @@ mod tests { ); } + #[test] + fn pin_decodes_supported_sync_settings_without_retired_keys() { + let complete = resolved(BTreeMap::from([ + ( + SettingKey::new(SYNC_WATCH_LINKED_WORKTREES_SETTING_KEY).unwrap(), + ConfigurationValueV1::Boolean(true), + ), + ( + SettingKey::new(SYNC_WATCH_DEBOUNCE_MS_SETTING_KEY).unwrap(), + ConfigurationValueV1::Unsigned(750), + ), + ( + SettingKey::new(SYNC_WATCH_MAX_PROJECTS_SETTING_KEY).unwrap(), + ConfigurationValueV1::Unsigned(12), + ), + ( + SettingKey::new(SYNC_READ_COOLDOWN_SECS_SETTING_KEY).unwrap(), + ConfigurationValueV1::Unsigned(45), + ), + ])); + let mut values = complete.effective_values; + let mut provenance = complete.provenance; + for raw_key in [ + "sync.full_sync_escalation_files.v1", + "sync.max_concurrent_syncs.v1", + ] { + let key = SettingKey::new(raw_key).unwrap(); + values.remove(&key); + provenance.remove(&key); + } + let snapshot = ConfigurationSnapshotV1::new(values, provenance).unwrap(); + + let pinned = PinnedRuntimeConfiguration::new(target(), revision(), snapshot).unwrap(); + + assert!(pinned.config().sync.watch_linked_worktrees); + assert_eq!(pinned.config().sync.watch_debounce_ms, 750); + assert_eq!(pinned.config().sync.watch_max_projects, 12); + assert_eq!(pinned.config().sync.read_cooldown_secs, 45); + assert!(pinned.config().sync.read_refresh); + } + #[test] fn pin_rejects_a_required_setting_with_the_wrong_type() { let complete = resolved(BTreeMap::new()); diff --git a/crates/tracedecay-configuration/src/config/model.rs b/crates/tracedecay-configuration/src/config/model.rs index 532c7b4dfe..5c06a25783 100644 --- a/crates/tracedecay-configuration/src/config/model.rs +++ b/crates/tracedecay-configuration/src/config/model.rs @@ -132,10 +132,6 @@ pub struct SyncConfig { pub session_start_stale_threshold_secs: u64, /// Daemon backstop scheduler interval (minutes); 0 disables it. pub backstop_interval_mins: u64, - /// Diff-scoped syncs above this many changed files escalate to a full sync. - pub full_sync_escalation_files: usize, - /// Daemon-wide cap on concurrent syncs. - pub max_concurrent_syncs: usize, /// Grace period before a dead tracked-branch store is GC'd (days). pub branch_gc_days: u64, /// Auto-initialise never-indexed repos on first contact. @@ -173,8 +169,6 @@ impl Default for SyncConfig { session_start_sync: true, session_start_stale_threshold_secs: 600, backstop_interval_mins: 15, - full_sync_escalation_files: 500, - max_concurrent_syncs: 2, branch_gc_days: 14, auto_init: true, auto_track_pr_branches: false, diff --git a/crates/tracedecay-configuration/src/configuration/operations.rs b/crates/tracedecay-configuration/src/configuration/operations.rs index 5f1295259e..8fd9f5c406 100644 --- a/crates/tracedecay-configuration/src/configuration/operations.rs +++ b/crates/tracedecay-configuration/src/configuration/operations.rs @@ -617,7 +617,7 @@ mod tests { use std::sync::Mutex; use super::*; - use crate::config::registry::ConfigurationRegistry; + use crate::config::registry::{ConfigurationRegistry, ConfigurationRegistryError}; use tracedecay_domain::configuration::{ AuthorityRef, ConfigurationGrantId, ConfigurationGrantReceiptId, ConfigurationLayerIdV1, ConfigurationMutationGrantReceiptV1, ConfigurationSnapshotV1, ConfigurationValueV1, @@ -825,6 +825,121 @@ mod tests { assert_eq!(result, Err(ConfigurationError::PolicyWideningForbidden)); } + #[test] + fn direct_mutation_rejects_retired_sync_settings() { + let registry = ConfigurationRegistry::core().unwrap(); + let layer = ConfigurationLayerIdV1::Project { + project_id: id::("project.configuration.sync"), + }; + let retained = DirectConfigurationMutation::Set { + layer: layer.clone(), + key: SettingKey::new("sync.watch_max_projects.v1").unwrap(), + value: Box::new(ConfigurationValueV1::Unsigned(7)), + }; + assert_eq!(validate_direct_mutation(®istry, &retained), Ok(())); + + for raw_key in [ + "sync.full_sync_escalation_files.v1", + "sync.max_concurrent_syncs.v1", + ] { + let key = SettingKey::new(raw_key).unwrap(); + let expected = ConfigurationError::validation( + ConfigurationRegistryError::UnknownSetting(key.clone()), + ); + let set = DirectConfigurationMutation::Set { + layer: layer.clone(), + key: key.clone(), + value: Box::new(ConfigurationValueV1::Unsigned(9)), + }; + for mutation in [ + set.clone(), + DirectConfigurationMutation::Unset { + layer: layer.clone(), + key, + }, + DirectConfigurationMutation::Batch { + mutations: vec![retained.clone(), set], + }, + ] { + assert_eq!( + validate_direct_mutation(®istry, &mutation), + Err(expected.clone()), + "retired settings must reject every direct write form: {mutation:?}" + ); + } + } + } + + #[asupersync::test] + async fn retired_sync_settings_are_absent_from_list_and_get() { + let registry = ConfigurationRegistry::core().unwrap(); + let store = Store { + current: ConfigurationCurrentStateV1 { + revision_id: id("configuration.revision.sync"), + snapshot: crate::config::resolver::resolve_configuration(®istry, &[]) + .unwrap() + .snapshot, + }, + saved: Mutex::new(None), + replay: Mutex::new(None), + }; + let authorization = Authorization { + current: CurrentConfigurationMutationAuthorizationV1 { + grant_revision: 1, + grant_digest: digest('c'), + scope_digest: digest('a'), + policy_epoch: 7, + policy_digest: policy_digest('b'), + }, + }; + let scope = Scope { + evidence: ScopeRevalidationEvidenceV1 { + resolved_scope_digest: digest('a'), + membership_digest: None, + authorization_policy_digest: policy_digest('b'), + policy_epoch: 7, + }, + }; + let operations = ConfigurationControlPlaneOperations::new( + ®istry, + &store, + &scope, + &authorization, + clock, + ); + let actor = AuthorizedActor { + actor_id: id::("actor.configuration.sync"), + }; + let listed = operations.list(actor.clone()).await.unwrap(); + let retained_key = SettingKey::new("sync.watch_max_projects.v1").unwrap(); + assert!(listed.iter().any(|setting| setting.key == retained_key)); + assert_eq!( + operations + .get(actor.clone(), retained_key) + .await + .unwrap() + .effective_value, + ConfigurationValueV1::Unsigned(32) + ); + + for raw_key in [ + "sync.full_sync_escalation_files.v1", + "sync.max_concurrent_syncs.v1", + ] { + let key = SettingKey::new(raw_key).unwrap(); + assert!( + !listed.iter().any(|setting| setting.key == key), + "{raw_key}" + ); + assert_eq!( + operations.get(actor.clone(), key.clone()).await, + Err(ConfigurationError::validation( + ConfigurationRegistryError::UnknownSetting(key) + )) + ); + } + } + #[test] fn current_authorization_must_match_scope_and_policy_evidence() { let authorization = CurrentConfigurationMutationAuthorizationV1 { diff --git a/crates/tracedecay-domain/src/configuration.rs b/crates/tracedecay-domain/src/configuration.rs index 304f2e80fd..1e708fe2df 100644 --- a/crates/tracedecay-domain/src/configuration.rs +++ b/crates/tracedecay-domain/src/configuration.rs @@ -56,10 +56,14 @@ pub const LCM_SUMMARIZER_EXECUTABLES_SETTING_KEY: &str = "lcm.summarizer_executa /// project's snapshot through v1.0.0-beta.61 and now live only in the profile /// store ([`PROFILE_SETTING_KEYS_V1`]). `diagnostics.prewarm.v1` shipped /// through v1.0.0-beta.83 and left with the compile-on-read cargo prewarm. +/// The full-sync escalation and concurrent-sync settings were retired because +/// sync execution does not read them. pub const RETIRED_CORE_SETTING_KEYS_V1: &[&str] = &[ "diagnostics.prewarm.v1", "index.git_ignore.v1", "semantic.runtime.v1", + "sync.full_sync_escalation_files.v1", + "sync.max_concurrent_syncs.v1", "sync.orphan_db_gc_days.v1", "user.upload_enabled.v1", USER_WATCHER_DEBOUNCE_MS_SETTING_KEY, @@ -112,8 +116,6 @@ pub const SYNC_SESSION_START_SYNC_SETTING_KEY: &str = "sync.session_start_sync.v pub const SYNC_SESSION_START_STALE_THRESHOLD_SECS_SETTING_KEY: &str = "sync.session_start_stale_threshold_secs.v1"; pub const SYNC_BACKSTOP_INTERVAL_MINS_SETTING_KEY: &str = "sync.backstop_interval_mins.v1"; -pub const SYNC_FULL_SYNC_ESCALATION_FILES_SETTING_KEY: &str = "sync.full_sync_escalation_files.v1"; -pub const SYNC_MAX_CONCURRENT_SYNCS_SETTING_KEY: &str = "sync.max_concurrent_syncs.v1"; pub const SYNC_BRANCH_GC_DAYS_SETTING_KEY: &str = "sync.branch_gc_days.v1"; pub const SYNC_AUTO_INIT_SETTING_KEY: &str = "sync.auto_init.v1"; pub const SYNC_AUTO_TRACK_PR_BRANCHES_SETTING_KEY: &str = "sync.auto_track_pr_branches.v1"; @@ -154,8 +156,6 @@ pub const CONFIGURATION_SETTING_KEYS_V1: &[&str] = &[ SYNC_SESSION_START_SYNC_SETTING_KEY, SYNC_SESSION_START_STALE_THRESHOLD_SECS_SETTING_KEY, SYNC_BACKSTOP_INTERVAL_MINS_SETTING_KEY, - SYNC_FULL_SYNC_ESCALATION_FILES_SETTING_KEY, - SYNC_MAX_CONCURRENT_SYNCS_SETTING_KEY, SYNC_BRANCH_GC_DAYS_SETTING_KEY, SYNC_AUTO_INIT_SETTING_KEY, SYNC_AUTO_TRACK_PR_BRANCHES_SETTING_KEY, diff --git a/crates/tracedecay-domain/src/lib.rs b/crates/tracedecay-domain/src/lib.rs index 946657283e..bbaf2a6595 100644 --- a/crates/tracedecay-domain/src/lib.rs +++ b/crates/tracedecay-domain/src/lib.rs @@ -115,8 +115,7 @@ pub use configuration::{ SOURCE_BINDINGS_SETTING_KEY, SYNC_AUTO_INIT_SETTING_KEY, SYNC_AUTO_TRACK_PR_BRANCHES_SETTING_KEY, SYNC_AUTO_TRACK_PR_POLL_SECS_SETTING_KEY, SYNC_AUTO_WATCH_SETTING_KEY, SYNC_BACKSTOP_INTERVAL_MINS_SETTING_KEY, - SYNC_BRANCH_GC_DAYS_SETTING_KEY, SYNC_FULL_SYNC_ESCALATION_FILES_SETTING_KEY, - SYNC_MAX_CONCURRENT_SYNCS_SETTING_KEY, SYNC_READ_COOLDOWN_SECS_SETTING_KEY, + SYNC_BRANCH_GC_DAYS_SETTING_KEY, SYNC_READ_COOLDOWN_SECS_SETTING_KEY, SYNC_READ_REFRESH_SETTING_KEY, SYNC_SESSION_START_STALE_THRESHOLD_SECS_SETTING_KEY, SYNC_SESSION_START_SYNC_SETTING_KEY, SYNC_WATCH_DEBOUNCE_MS_SETTING_KEY, SYNC_WATCH_LINKED_WORKTREES_SETTING_KEY, SYNC_WATCH_MAX_DELAY_MS_SETTING_KEY, diff --git a/crates/tracedecay-global-db/src/configuration/registry.rs b/crates/tracedecay-global-db/src/configuration/registry.rs index e31e1ece16..0b577c46de 100644 --- a/crates/tracedecay-global-db/src/configuration/registry.rs +++ b/crates/tracedecay-global-db/src/configuration/registry.rs @@ -16,7 +16,6 @@ use tracedecay_domain::configuration::{ SYNC_AUTO_INIT_SETTING_KEY, SYNC_AUTO_TRACK_PR_BRANCHES_SETTING_KEY, SYNC_AUTO_TRACK_PR_POLL_SECS_SETTING_KEY, SYNC_AUTO_WATCH_SETTING_KEY, SYNC_BACKSTOP_INTERVAL_MINS_SETTING_KEY, SYNC_BRANCH_GC_DAYS_SETTING_KEY, - SYNC_FULL_SYNC_ESCALATION_FILES_SETTING_KEY, SYNC_MAX_CONCURRENT_SYNCS_SETTING_KEY, SYNC_READ_COOLDOWN_SECS_SETTING_KEY, SYNC_READ_REFRESH_SETTING_KEY, SYNC_SESSION_START_STALE_THRESHOLD_SECS_SETTING_KEY, SYNC_SESSION_START_SYNC_SETTING_KEY, SYNC_WATCH_DEBOUNCE_MS_SETTING_KEY, SYNC_WATCH_LINKED_WORKTREES_SETTING_KEY, @@ -483,8 +482,6 @@ struct SyncDefaults { session_start_sync: bool, session_start_stale_threshold_secs: u64, backstop_interval_mins: u64, - full_sync_escalation_files: usize, - max_concurrent_syncs: usize, branch_gc_days: u64, auto_init: bool, auto_track_pr_branches: bool, @@ -504,8 +501,6 @@ impl Default for SyncDefaults { session_start_sync: true, session_start_stale_threshold_secs: 600, backstop_interval_mins: 15, - full_sync_escalation_files: 500, - max_concurrent_syncs: 2, branch_gc_days: 14, auto_init: true, auto_track_pr_branches: false, @@ -641,18 +636,6 @@ fn register_project_settings( SettingSensitivityV1::Public, RestartRequirementV1::DaemonRestart, ), - ( - SYNC_FULL_SYNC_ESCALATION_FILES_SETTING_KEY, - ConfigurationValueV1::Unsigned(sync.full_sync_escalation_files as u64), - SettingSensitivityV1::Public, - RestartRequirementV1::DaemonRestart, - ), - ( - SYNC_MAX_CONCURRENT_SYNCS_SETTING_KEY, - ConfigurationValueV1::Unsigned(sync.max_concurrent_syncs as u64), - SettingSensitivityV1::Public, - RestartRequirementV1::DaemonRestart, - ), ( SYNC_BRANCH_GC_DAYS_SETTING_KEY, ConfigurationValueV1::Unsigned(sync.branch_gc_days), diff --git a/crates/tracedecay-global-db/src/configuration/store/tests/mod.rs b/crates/tracedecay-global-db/src/configuration/store/tests/mod.rs index 873af7e58a..a04cf19eb8 100644 --- a/crates/tracedecay-global-db/src/configuration/store/tests/mod.rs +++ b/crates/tracedecay-global-db/src/configuration/store/tests/mod.rs @@ -586,3 +586,4 @@ fn evidence_for(plan: &ProtectedChangePlan) -> ScopeRevalidationEvidenceV1 { mod control; mod persistence; mod receipt_writer; +mod retired_sync; diff --git a/crates/tracedecay-global-db/src/configuration/store/tests/retired_sync.rs b/crates/tracedecay-global-db/src/configuration/store/tests/retired_sync.rs new file mode 100644 index 0000000000..09f59ae548 --- /dev/null +++ b/crates/tracedecay-global-db/src/configuration/store/tests/retired_sync.rs @@ -0,0 +1,221 @@ +//! Released sync settings retire without changing supported policy or history. + +use super::super::mutation::commit_direct_in_transaction_with_registry; +use super::super::{ + ConfigurationControlStore, ConfigurationError, ConfigurationRevisionStore, + GlobalDbConfigurationControlStore, +}; +use super::{ + HostAdmissionScope, HostAdmissionTestRuntimeV1, control_authority, count, direct_project_layer, + global_setup, id, +}; +use crate::configuration::contracts::DirectConfigurationMutation; +use crate::configuration::registry::{ConfigurationRegistry, ConfigurationRegistryError}; +use crate::configuration::resolver::resolve_configuration; +use tracedecay_domain::UtcMicros; +use tracedecay_domain::configuration::{ + ConfigurationMutationOperationV1, ConfigurationSnapshotV1, ConfigurationValueKindV1, + ConfigurationValueV1, DeprecationStateV1, RestartRequirementV1, + SYNC_READ_COOLDOWN_SECS_SETTING_KEY, SettingDefinitionV1, SettingKey, SettingScopeV1, + SettingSensitivityV1, +}; + +// These defaults and descriptors shipped before the controls were retired. +const RELEASED_SYNC_SETTINGS: [(&str, u64); 2] = [ + ("sync.full_sync_escalation_files.v1", 500), + ("sync.max_concurrent_syncs.v1", 2), +]; + +#[asupersync::test] +async fn retired_sync_defaults_converge_without_reset_or_history_rewrite() { + assert_sync_retirement_preserves_history(false).await; +} + +#[asupersync::test] +async fn retired_sync_overrides_converge_without_losing_supported_policy() { + assert_sync_retirement_preserves_history(true).await; +} + +async fn assert_sync_retirement_preserves_history(override_retired: bool) { + let mut released = ConfigurationRegistry::core().unwrap(); + for (raw_key, default) in RELEASED_SYNC_SETTINGS { + released + .register(SettingDefinitionV1 { + key: SettingKey::new(raw_key).unwrap(), + schema_revision: 7, + value_kind: ConfigurationValueKindV1::Unsigned, + default_value: ConfigurationValueV1::Unsigned(default), + sensitivity: SettingSensitivityV1::Public, + scope: SettingScopeV1::Project, + restart_requirement: RestartRequirementV1::DaemonRestart, + deprecation: DeprecationStateV1::Active, + }) + .unwrap(); + } + let directory = tempfile::tempdir().unwrap(); + let profile_root = directory.path().join("profile"); + let project_root = directory.path().join("project"); + std::fs::create_dir_all(&project_root).unwrap(); + let runtime = HostAdmissionTestRuntimeV1::project( + &profile_root, + &project_root, + id("project.configuration-store.fixture"), + ) + .await + .unwrap(); + let db = runtime + .registered_database(HostAdmissionScope::Project) + .unwrap(); + let store = GlobalDbConfigurationControlStore::new_registered(db); + let initial_revision = id("configuration.revision.released-sync"); + store + .initialize_canonical_with_registry( + &initial_revision, + &resolve_configuration(&released, &[]).unwrap(), + UtcMicros(1), + &released, + ) + .await + .unwrap(); + let initial = store.current_revision().await.unwrap(); + + let cooldown = SettingKey::new(SYNC_READ_COOLDOWN_SECS_SETTING_KEY).unwrap(); + let mut mutations = vec![DirectConfigurationMutation::Set { + layer: direct_project_layer(), + key: cooldown.clone(), + value: Box::new(ConfigurationValueV1::Unsigned(83)), + }]; + if override_retired { + mutations.extend(RELEASED_SYNC_SETTINGS.into_iter().zip([900, 7]).map( + |((raw_key, _), value)| DirectConfigurationMutation::Set { + layer: direct_project_layer(), + key: SettingKey::new(raw_key).unwrap(), + value: Box::new(ConfigurationValueV1::Unsigned(value)), + }, + )); + } + let authority = control_authority( + ConfigurationMutationOperationV1::DirectMutation, + &initial_revision, + ); + let transaction = db.begin_write_transaction().await.unwrap(); + commit_direct_in_transaction_with_registry( + &transaction, + &authority, + &DirectConfigurationMutation::Batch { mutations }, + &initial_revision, + &released, + ) + .await + .unwrap(); + transaction.commit().await.unwrap(); + let historical = store.current_revision().await.unwrap(); + + let mut expected_values = historical.snapshot.effective_values.clone(); + let mut expected_provenance = historical.snapshot.provenance.clone(); + for ((raw_key, default), overridden) in RELEASED_SYNC_SETTINGS.into_iter().zip([900, 7]) { + let key = SettingKey::new(raw_key).unwrap(); + assert_eq!( + expected_values.remove(&key), + Some(ConfigurationValueV1::Unsigned(if override_retired { + overridden + } else { + default + })) + ); + assert!(expected_provenance.remove(&key).is_some()); + } + let expected = ConfigurationSnapshotV1::new(expected_values, expected_provenance).unwrap(); + + let converged = store + .converge_registered_registry_shape(&historical.revision_id, UtcMicros(20)) + .await + .unwrap(); + assert_ne!(converged.revision_id, historical.revision_id); + assert_eq!(converged.snapshot, expected); + assert_eq!( + converged.snapshot.effective_values[&cooldown], + ConfigurationValueV1::Unsigned(83) + ); + assert_eq!( + converged.snapshot.provenance[&cooldown], + historical.snapshot.provenance[&cooldown] + ); + let current = store.current_revision().await.unwrap(); + assert_eq!(current.revision_id, converged.revision_id); + assert_eq!( + current.parent_revision_id, + Some(historical.revision_id.clone()) + ); + assert_eq!(current.operation_kind, "registry_shape_convergence"); + assert_eq!( + store.read_revision(&historical.revision_id).await.unwrap(), + Some(historical) + ); + assert_eq!( + store.read_revision(&initial_revision).await.unwrap(), + Some(initial) + ); + assert_eq!( + store + .converge_registered_registry_shape(&converged.revision_id, UtcMicros(21)) + .await + .unwrap(), + converged, + "reopening the current shape must not create another revision" + ); +} + +#[asupersync::test] +async fn retired_sync_settings_are_absent_and_writes_are_rejected() { + let registry = ConfigurationRegistry::core().unwrap(); + let (_directory, runtime, root) = Box::pin(global_setup()).await; + let db = runtime + .registered_database(HostAdmissionScope::Project) + .unwrap(); + let store = GlobalDbConfigurationControlStore::new_registered(db); + let authority = control_authority( + ConfigurationMutationOperationV1::DirectMutation, + &root.revision_id, + ); + + for (raw_key, default) in RELEASED_SYNC_SETTINGS { + let key = SettingKey::new(raw_key).unwrap(); + assert!( + registry + .definitions() + .all(|definition| definition.key != key) + ); + assert!(matches!( + registry.definition(&key), + Err(ConfigurationRegistryError::UnknownSetting(rejected)) if rejected == key + )); + assert!(!root.snapshot.effective_values.contains_key(&key)); + assert!(!root.snapshot.provenance.contains_key(&key)); + + for mutation in [ + DirectConfigurationMutation::Set { + layer: direct_project_layer(), + key: key.clone(), + value: Box::new(ConfigurationValueV1::Unsigned(default)), + }, + DirectConfigurationMutation::Unset { + layer: direct_project_layer(), + key: key.clone(), + }, + ] { + assert_eq!( + store + .commit_direct(&authority, &mutation, &root.revision_id) + .await, + Err(ConfigurationError::Validation(format!( + "setting key is not registered: {raw_key}" + ))) + ); + assert_eq!(store.current_revision().await.unwrap(), root); + } + } + let read = db.read_snapshot().await.unwrap(); + assert_eq!(count(&read, "configuration_mutation_receipts").await, 0); + assert_eq!(count(&read, "configuration_audit_events").await, 0); +} From f419918c0c8a53b86127eca53746022b492e92d2 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Mon, 26 Oct 2026 08:58:06 +0000 Subject: [PATCH 5/8] simplify(search-eval): embed the canonical corpus Restack unique #4530 onto the rewritten #4528 tip. --- .gitattributes | 9 +- crates/tracedecay-query/BUILD.bazel | 29 +- .../evals/agent_adoption/fixture/Cargo.lock | 7 - .../context_eval_project/src/auth/login.rs | 19 - .../context_eval_project/src/auth/session.rs | 29 - .../context_eval_project/src/net/retry.rs | 45 - .../src/storage/config_store.rs | 42 - .../tests/fixtures/sample.dockerfile | 37 - .../corpus/cargo-slot/src/main.rust.fixture | 6 - .../tracedecay-domain/src/integration.rs | 652 ----- .../tracedecay-domain/src/repository.rs | 639 ----- .../src/research/canonical.rs | 158 -- .../src/research/coverage.rs | 672 ------ .../tracedecay-domain/src/research/error.rs | 38 - .../tracedecay-domain/src/research/time.rs | 25 - .../src/research/watermark.rs | 50 - .../crates/tracedecay-domain/src/session.rs | 2114 ----------------- .../src/search_quality/packaged.rs | 38 +- .../src/packaged_assets.rs | 94 + .../src/report_tests.rs | 2 +- evals/agent_adoption/BUILD.bazel | 8 + scripts/bazel/gen_builds.py | 26 +- scripts/test-gen-builds-default-alias.py | 35 + tests/BUILD.bazel | 72 +- .../query-lexical-graph-workload-v1.json | 0 25 files changed, 262 insertions(+), 4584 deletions(-) delete mode 100644 crates/tracedecay-query/assets/runtime-root/evals/agent_adoption/fixture/Cargo.lock delete mode 100644 crates/tracedecay-query/assets/runtime-root/tests/fixtures/context_eval_project/src/auth/login.rs delete mode 100644 crates/tracedecay-query/assets/runtime-root/tests/fixtures/context_eval_project/src/auth/session.rs delete mode 100644 crates/tracedecay-query/assets/runtime-root/tests/fixtures/context_eval_project/src/net/retry.rs delete mode 100644 crates/tracedecay-query/assets/runtime-root/tests/fixtures/context_eval_project/src/storage/config_store.rs delete mode 100644 crates/tracedecay-query/assets/runtime-root/tests/fixtures/sample.dockerfile delete mode 100644 crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/cargo-slot/src/main.rust.fixture delete mode 100644 crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/integration.rs delete mode 100644 crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/repository.rs delete mode 100644 crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/canonical.rs delete mode 100644 crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/coverage.rs delete mode 100644 crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/error.rs delete mode 100644 crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/time.rs delete mode 100644 crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/watermark.rs delete mode 100644 crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/session.rs rename {crates/tracedecay-query/assets/runtime-root/tests => tests}/fixtures/search_quality/query-lexical-graph-workload-v1.json (100%) diff --git a/.gitattributes b/.gitattributes index be8151c047..6b158206fe 100644 --- a/.gitattributes +++ b/.gitattributes @@ -10,13 +10,10 @@ tests/fixtures/** text eol=lf # schema-shape digests; a CRLF checkout rewrites those definitions and makes # a released shape read as foreign. *.sql text eol=lf -# The search-quality candidate workload pins each corpus document against the -# blob in the pinned source tree, and the packaged evaluator assets are pulled -# into the binary with include_bytes! under a pinned digest. One corpus -# document lives outside tests/fixtures, and the packaged mirror is a separate -# tree; a CRLF checkout rewrites either and fails both byte-exact contracts. +# The search-quality workload pins each corpus document against the blob in +# its source tree; the packaged evaluator embeds those same fixture bytes. +# One corpus document lives outside tests/fixtures, so enforce LF there too. evals/agent_adoption/fixture/** text eol=lf -crates/tracedecay-query/assets/runtime-root/** text eol=lf # Force LF for bundled plugin skill docs; the skill hygiene tests assert the # canonical source files are LF-only, and Windows checkout otherwise rewrites # them before the lint runs. diff --git a/crates/tracedecay-query/BUILD.bazel b/crates/tracedecay-query/BUILD.bazel index e1499a70d6..e727bf8982 100644 --- a/crates/tracedecay-query/BUILD.bazel +++ b/crates/tracedecay-query/BUILD.bazel @@ -15,7 +15,7 @@ rust_library( crate_name = "tracedecay_query", edition = crate_edition(), compile_data = glob(["src/**/*"], exclude=["src/**/*.rs"], allow_empty = True) - + glob(["assets/**","fixtures/**","data/**","resources/**","vendor/**"], allow_empty = True), + + glob(["assets/**","fixtures/**","data/**","resources/**","vendor/**"], allow_empty = True) + ["//evals/agent_adoption:fixture", "//tests:fixtures_context_eval_project_src_auth", "//tests:fixtures_context_eval_project_src_net", "//tests:fixtures_context_eval_project_src_storage", "//tests:fixtures_search_quality", "//tests:fixtures_search_quality_corpus_cargo-slot_src", "//tests:fixtures_search_quality_corpus_crates_tracedecay-domain_src", "//tests:fixtures_search_quality_corpus_crates_tracedecay-domain_src_research", "//tests:shared_fixtures"], version = "0.1.0", deps = all_crate_deps(normal = True) + ["//crates/tracedecay-code-index:tracedecay-code-index__bare__d5f4099fe25", "//crates/tracedecay-contracts:tracedecay-contracts", "//crates/tracedecay-domain:tracedecay-domain", "//crates/tracedecay-graph-db:tracedecay-graph-db", "//crates/tracedecay-private-fs:tracedecay-private-fs", "//crates/tracedecay-runtime-core:tracedecay-runtime-core", "//crates/tracedecay-temporal-query:tracedecay-temporal-query"], proc_macro_deps = all_crate_deps(proc_macro = True), @@ -31,7 +31,7 @@ rust_library( crate_name = "tracedecay_query", edition = crate_edition(), compile_data = glob(["src/**/*"], exclude=["src/**/*.rs"], allow_empty = True) - + glob(["assets/**","fixtures/**","data/**","resources/**","vendor/**"], allow_empty = True), + + glob(["assets/**","fixtures/**","data/**","resources/**","vendor/**"], allow_empty = True) + ["//evals/agent_adoption:fixture", "//tests:fixtures_context_eval_project_src_auth", "//tests:fixtures_context_eval_project_src_net", "//tests:fixtures_context_eval_project_src_storage", "//tests:fixtures_search_quality", "//tests:fixtures_search_quality_corpus_cargo-slot_src", "//tests:fixtures_search_quality_corpus_crates_tracedecay-domain_src", "//tests:fixtures_search_quality_corpus_crates_tracedecay-domain_src_research", "//tests:shared_fixtures"], version = "0.1.0", deps = all_crate_deps(normal = True) + ["//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev"], proc_macro_deps = all_crate_deps(proc_macro = True), @@ -47,7 +47,7 @@ rust_library( crate_name = "tracedecay_query", edition = crate_edition(), compile_data = glob(["src/**/*"], exclude=["src/**/*.rs"], allow_empty = True) - + glob(["assets/**","fixtures/**","data/**","resources/**","vendor/**"], allow_empty = True), + + glob(["assets/**","fixtures/**","data/**","resources/**","vendor/**"], allow_empty = True) + ["//evals/agent_adoption:fixture", "//tests:fixtures_context_eval_project_src_auth", "//tests:fixtures_context_eval_project_src_net", "//tests:fixtures_context_eval_project_src_storage", "//tests:fixtures_search_quality", "//tests:fixtures_search_quality_corpus_cargo-slot_src", "//tests:fixtures_search_quality_corpus_crates_tracedecay-domain_src", "//tests:fixtures_search_quality_corpus_crates_tracedecay-domain_src_research", "//tests:shared_fixtures"], version = "0.1.0", deps = all_crate_deps(normal = True) + ["//crates/tracedecay-code-index:tracedecay-code-index__-default_-medium__d6a7dfc4236", "//crates/tracedecay-contracts:tracedecay-contracts", "//crates/tracedecay-domain:tracedecay-domain", "//crates/tracedecay-graph-db:tracedecay-graph-db", "//crates/tracedecay-private-fs:tracedecay-private-fs", "//crates/tracedecay-runtime-core:tracedecay-runtime-core", "//crates/tracedecay-temporal-query:tracedecay-temporal-query"], proc_macro_deps = all_crate_deps(proc_macro = True), @@ -63,7 +63,7 @@ rust_library( crate_name = "tracedecay_query", edition = crate_edition(), compile_data = glob(["src/**/*"], exclude=["src/**/*.rs"], allow_empty = True) - + glob(["assets/**","fixtures/**","data/**","resources/**","vendor/**"], allow_empty = True), + + glob(["assets/**","fixtures/**","data/**","resources/**","vendor/**"], allow_empty = True) + ["//evals/agent_adoption:fixture", "//tests:fixtures_context_eval_project_src_auth", "//tests:fixtures_context_eval_project_src_net", "//tests:fixtures_context_eval_project_src_storage", "//tests:fixtures_search_quality", "//tests:fixtures_search_quality_corpus_cargo-slot_src", "//tests:fixtures_search_quality_corpus_crates_tracedecay-domain_src", "//tests:fixtures_search_quality_corpus_crates_tracedecay-domain_src_research", "//tests:shared_fixtures"], version = "0.1.0", deps = all_crate_deps(normal = True) + ["//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_-default_-full_-lang-markdown_-lite_-medium__d6f240ed6cb", "//crates/tracedecay-contracts:tracedecay-contracts", "//crates/tracedecay-domain:tracedecay-domain", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers__d73c9d40925", "//crates/tracedecay-private-fs:tracedecay-private-fs", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__db496041207", "//crates/tracedecay-temporal-query:tracedecay-temporal-query"], proc_macro_deps = all_crate_deps(proc_macro = True), @@ -79,7 +79,7 @@ rust_library( crate_name = "tracedecay_query", edition = crate_edition(), compile_data = glob(["src/**/*"], exclude=["src/**/*.rs"], allow_empty = True) - + glob(["assets/**","fixtures/**","data/**","resources/**","vendor/**"], allow_empty = True), + + glob(["assets/**","fixtures/**","data/**","resources/**","vendor/**"], allow_empty = True) + ["//evals/agent_adoption:fixture", "//tests:fixtures_context_eval_project_src_auth", "//tests:fixtures_context_eval_project_src_net", "//tests:fixtures_context_eval_project_src_storage", "//tests:fixtures_search_quality", "//tests:fixtures_search_quality_corpus_cargo-slot_src", "//tests:fixtures_search_quality_corpus_crates_tracedecay-domain_src", "//tests:fixtures_search_quality_corpus_crates_tracedecay-domain_src_research", "//tests:shared_fixtures"], version = "0.1.0", deps = all_crate_deps(normal = True) + ["//crates/tracedecay-code-index:tracedecay-code-index__bare__d455cac0e1d", "//crates/tracedecay-contracts:tracedecay-contracts", "//crates/tracedecay-domain:tracedecay-domain", "//crates/tracedecay-graph-db:tracedecay-graph-db", "//crates/tracedecay-private-fs:tracedecay-private-fs", "//crates/tracedecay-runtime-core:tracedecay-runtime-core", "//crates/tracedecay-temporal-query:tracedecay-temporal-query"], proc_macro_deps = all_crate_deps(proc_macro = True), @@ -95,7 +95,7 @@ rust_library( crate_name = "tracedecay_query", edition = crate_edition(), compile_data = glob(["src/**/*"], exclude=["src/**/*.rs"], allow_empty = True) - + glob(["assets/**","fixtures/**","data/**","resources/**","vendor/**"], allow_empty = True), + + glob(["assets/**","fixtures/**","data/**","resources/**","vendor/**"], allow_empty = True) + ["//evals/agent_adoption:fixture", "//tests:fixtures_context_eval_project_src_auth", "//tests:fixtures_context_eval_project_src_net", "//tests:fixtures_context_eval_project_src_storage", "//tests:fixtures_search_quality", "//tests:fixtures_search_quality_corpus_cargo-slot_src", "//tests:fixtures_search_quality_corpus_crates_tracedecay-domain_src", "//tests:fixtures_search_quality_corpus_crates_tracedecay-domain_src_research", "//tests:shared_fixtures"], version = "0.1.0", deps = all_crate_deps(normal = True) + ["//crates/tracedecay-code-index:tracedecay-code-index__-default_-medium__d6a7dfc4236", "//crates/tracedecay-contracts:tracedecay-contracts", "//crates/tracedecay-domain:tracedecay-domain", "//crates/tracedecay-graph-db:tracedecay-graph-db", "//crates/tracedecay-private-fs:tracedecay-private-fs", "//crates/tracedecay-runtime-core:tracedecay-runtime-core", "//crates/tracedecay-temporal-query:tracedecay-temporal-query"], proc_macro_deps = all_crate_deps(proc_macro = True), @@ -111,7 +111,7 @@ rust_library( crate_name = "tracedecay_query", edition = crate_edition(), compile_data = glob(["src/**/*"], exclude=["src/**/*.rs"], allow_empty = True) - + glob(["assets/**","fixtures/**","data/**","resources/**","vendor/**"], allow_empty = True), + + glob(["assets/**","fixtures/**","data/**","resources/**","vendor/**"], allow_empty = True) + ["//evals/agent_adoption:fixture", "//tests:fixtures_context_eval_project_src_auth", "//tests:fixtures_context_eval_project_src_net", "//tests:fixtures_context_eval_project_src_storage", "//tests:fixtures_search_quality", "//tests:fixtures_search_quality_corpus_cargo-slot_src", "//tests:fixtures_search_quality_corpus_crates_tracedecay-domain_src", "//tests:fixtures_search_quality_corpus_crates_tracedecay-domain_src_research", "//tests:shared_fixtures"], version = "0.1.0", deps = all_crate_deps(normal = True) + ["//crates/tracedecay-code-index:tracedecay-code-index__-default_-full_-medium__d480e0ce7ad", "//crates/tracedecay-contracts:tracedecay-contracts", "//crates/tracedecay-domain:tracedecay-domain", "//crates/tracedecay-graph-db:tracedecay-graph-db", "//crates/tracedecay-private-fs:tracedecay-private-fs", "//crates/tracedecay-runtime-core:tracedecay-runtime-core", "//crates/tracedecay-temporal-query:tracedecay-temporal-query"], proc_macro_deps = all_crate_deps(proc_macro = True), @@ -125,7 +125,8 @@ rust_binary( srcs = glob(["src/**/*.rs"]), crate_root = "src/bin/tracedecay_index_bench.rs", edition = crate_edition(), - compile_data = glob(["src/**/*"], exclude=["src/**/*.rs"], allow_empty = True), + compile_data = glob(["src/**/*"], exclude=["src/**/*.rs"], allow_empty = True) + + ["//evals/agent_adoption:fixture", "//tests:fixtures_context_eval_project_src_auth", "//tests:fixtures_context_eval_project_src_net", "//tests:fixtures_context_eval_project_src_storage", "//tests:fixtures_search_quality", "//tests:fixtures_search_quality_corpus_cargo-slot_src", "//tests:fixtures_search_quality_corpus_crates_tracedecay-domain_src", "//tests:fixtures_search_quality_corpus_crates_tracedecay-domain_src_research", "//tests:shared_fixtures"], version = "0.1.0", deps = all_crate_deps(normal = True) + ["//crates/tracedecay-query:tracedecay-query__+production__d56d68a5bbd", "//crates/tracedecay-code-index:tracedecay-code-index__-default_-medium__d6a7dfc4236", "//crates/tracedecay-contracts:tracedecay-contracts", "//crates/tracedecay-domain:tracedecay-domain", "//crates/tracedecay-graph-db:tracedecay-graph-db", "//crates/tracedecay-private-fs:tracedecay-private-fs", "//crates/tracedecay-runtime-core:tracedecay-runtime-core", "//crates/tracedecay-temporal-query:tracedecay-temporal-query"], proc_macro_deps = all_crate_deps(proc_macro = True), @@ -142,7 +143,8 @@ rust_binary( srcs = glob(["src/**/*.rs"]), crate_root = "src/bin/tracedecay_index_bench.rs", edition = crate_edition(), - compile_data = glob(["src/**/*"], exclude=["src/**/*.rs"], allow_empty = True), + compile_data = glob(["src/**/*"], exclude=["src/**/*.rs"], allow_empty = True) + + ["//evals/agent_adoption:fixture", "//tests:fixtures_context_eval_project_src_auth", "//tests:fixtures_context_eval_project_src_net", "//tests:fixtures_context_eval_project_src_storage", "//tests:fixtures_search_quality", "//tests:fixtures_search_quality_corpus_cargo-slot_src", "//tests:fixtures_search_quality_corpus_crates_tracedecay-domain_src", "//tests:fixtures_search_quality_corpus_crates_tracedecay-domain_src_research", "//tests:shared_fixtures"], version = "0.1.0", deps = all_crate_deps(normal = True) + ["//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev"], proc_macro_deps = all_crate_deps(proc_macro = True), @@ -156,7 +158,8 @@ rust_binary( srcs = glob(["src/**/*.rs"]), crate_root = "src/bin/tracedecay_search_bench.rs", edition = crate_edition(), - compile_data = glob(["src/**/*"], exclude=["src/**/*.rs"], allow_empty = True), + compile_data = glob(["src/**/*"], exclude=["src/**/*.rs"], allow_empty = True) + + ["//evals/agent_adoption:fixture", "//tests:fixtures_context_eval_project_src_auth", "//tests:fixtures_context_eval_project_src_net", "//tests:fixtures_context_eval_project_src_storage", "//tests:fixtures_search_quality", "//tests:fixtures_search_quality_corpus_cargo-slot_src", "//tests:fixtures_search_quality_corpus_crates_tracedecay-domain_src", "//tests:fixtures_search_quality_corpus_crates_tracedecay-domain_src_research", "//tests:shared_fixtures"], version = "0.1.0", deps = all_crate_deps(normal = True) + ["//crates/tracedecay-query:tracedecay-query", "//crates/tracedecay-code-index:tracedecay-code-index__bare__d5f4099fe25", "//crates/tracedecay-contracts:tracedecay-contracts", "//crates/tracedecay-domain:tracedecay-domain", "//crates/tracedecay-graph-db:tracedecay-graph-db", "//crates/tracedecay-private-fs:tracedecay-private-fs", "//crates/tracedecay-runtime-core:tracedecay-runtime-core", "//crates/tracedecay-temporal-query:tracedecay-temporal-query"], proc_macro_deps = all_crate_deps(proc_macro = True), @@ -173,7 +176,8 @@ rust_binary( srcs = glob(["src/**/*.rs"]), crate_root = "src/bin/tracedecay_search_bench.rs", edition = crate_edition(), - compile_data = glob(["src/**/*"], exclude=["src/**/*.rs"], allow_empty = True), + compile_data = glob(["src/**/*"], exclude=["src/**/*.rs"], allow_empty = True) + + ["//evals/agent_adoption:fixture", "//tests:fixtures_context_eval_project_src_auth", "//tests:fixtures_context_eval_project_src_net", "//tests:fixtures_context_eval_project_src_storage", "//tests:fixtures_search_quality", "//tests:fixtures_search_quality_corpus_cargo-slot_src", "//tests:fixtures_search_quality_corpus_crates_tracedecay-domain_src", "//tests:fixtures_search_quality_corpus_crates_tracedecay-domain_src_research", "//tests:shared_fixtures"], version = "0.1.0", deps = all_crate_deps(normal = True) + ["//crates/tracedecay-query:tracedecay-query__+production_+test-helpers__dev", "//crates/tracedecay-code-index:tracedecay-code-index__+eval-helpers_+lang-dockerfile_+test-helpers__dev", "//crates/tracedecay-contracts:tracedecay-contracts__dev", "//crates/tracedecay-domain:tracedecay-domain__dev", "//crates/tracedecay-graph-db:tracedecay-graph-db__+eval-helpers_+test-helpers__dev", "//crates/tracedecay-private-fs:tracedecay-private-fs__+test-helpers__dev", "//crates/tracedecay-runtime-core:tracedecay-runtime-core__+test-helpers_+test-transport__dev", "//crates/tracedecay-temporal-query:tracedecay-temporal-query__+test-helpers__dev"], proc_macro_deps = all_crate_deps(proc_macro = True), @@ -282,7 +286,8 @@ rust_test( proc_macro_deps = all_crate_deps(proc_macro = True, proc_macro_dev = True), aliases = aliases(normal = True, normal_dev = True), rustc_flags = perf_rustc_flags(1), - compile_data = glob(["tests/**","assets/**","fixtures/**","data/**","resources/**","vendor/**"], allow_empty = True), + compile_data = glob(["tests/**","assets/**","fixtures/**","data/**","resources/**","vendor/**"], allow_empty = True) + + ["//evals/agent_adoption:fixture", "//tests:fixtures_context_eval_project_src_auth", "//tests:fixtures_context_eval_project_src_net", "//tests:fixtures_context_eval_project_src_storage", "//tests:fixtures_search_quality", "//tests:fixtures_search_quality_corpus_cargo-slot_src", "//tests:fixtures_search_quality_corpus_crates_tracedecay-domain_src", "//tests:fixtures_search_quality_corpus_crates_tracedecay-domain_src_research", "//tests:shared_fixtures"], data = glob(["tests/**","assets/**","fixtures/**","data/**","resources/**","vendor/**"], allow_empty = True) + ["//tests:fixtures"], ) diff --git a/crates/tracedecay-query/assets/runtime-root/evals/agent_adoption/fixture/Cargo.lock b/crates/tracedecay-query/assets/runtime-root/evals/agent_adoption/fixture/Cargo.lock deleted file mode 100644 index eb4a1fe284..0000000000 --- a/crates/tracedecay-query/assets/runtime-root/evals/agent_adoption/fixture/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "orders_fixture" -version = "0.0.0" diff --git a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/context_eval_project/src/auth/login.rs b/crates/tracedecay-query/assets/runtime-root/tests/fixtures/context_eval_project/src/auth/login.rs deleted file mode 100644 index 695569c048..0000000000 --- a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/context_eval_project/src/auth/login.rs +++ /dev/null @@ -1,19 +0,0 @@ -//! Credential checking for interactive login. - -use crate::auth::session::{Session, create_session}; - -/// Checks a username/password pair and, on success, creates a new -/// authenticated session. This is the entry point for "how does -/// authentication work" style questions. -pub fn authenticate(username: &str, password: &str) -> Result { - if !credentials_are_valid(username, password) { - return Err("invalid username or password".to_string()); - } - Ok(create_session(username)) -} - -/// Very small stand-in for a real credential check: non-empty username and -/// a password of at least 8 characters. -fn credentials_are_valid(username: &str, password: &str) -> bool { - !username.is_empty() && password.len() >= 8 -} diff --git a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/context_eval_project/src/auth/session.rs b/crates/tracedecay-query/assets/runtime-root/tests/fixtures/context_eval_project/src/auth/session.rs deleted file mode 100644 index 2d15af2288..0000000000 --- a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/context_eval_project/src/auth/session.rs +++ /dev/null @@ -1,29 +0,0 @@ -//! Session lifecycle: creating sessions after login and validating session -//! tokens on later requests. - -/// A logged-in user's session: a bearer token and the user it belongs to. -pub struct Session { - pub username: String, - pub token: String, - pub expires_at_secs: u64, -} - -/// Creates a new session for `username` with a freshly generated token. -/// Called by `auth::login::authenticate` after credentials are checked. -pub fn create_session(username: &str) -> Session { - Session { - username: username.to_string(), - token: generate_token(username), - expires_at_secs: 3600, - } -} - -/// Checks whether `session` is still within its validity window. Used on -/// every authenticated request to reject expired tokens. -pub fn validate_session(session: &Session, now_secs: u64) -> bool { - now_secs < session.expires_at_secs -} - -fn generate_token(username: &str) -> String { - format!("tok_{username}_{}", username.len()) -} diff --git a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/context_eval_project/src/net/retry.rs b/crates/tracedecay-query/assets/runtime-root/tests/fixtures/context_eval_project/src/net/retry.rs deleted file mode 100644 index 889a1c8cb4..0000000000 --- a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/context_eval_project/src/net/retry.rs +++ /dev/null @@ -1,45 +0,0 @@ -//! Retry-with-backoff logic used by the HTTP client for transient network -//! failures. This is the entry point for "where is the retry logic" -//! style questions. - -/// Configuration for how many attempts to make and how long to wait -/// between them. -pub struct RetryPolicy { - pub max_attempts: u32, - pub base_delay_ms: u64, -} - -impl RetryPolicy { - pub fn new(max_attempts: u32, base_delay_ms: u64) -> Self { - RetryPolicy { - max_attempts, - base_delay_ms, - } - } - - /// Exponential backoff delay before attempt number `attempt` (0-based). - pub fn delay_for_attempt(&self, attempt: u32) -> u64 { - self.base_delay_ms * 2u64.pow(attempt) - } -} - -/// Retries `operation` up to `policy.max_attempts` times, doubling the -/// delay between attempts, until it succeeds or attempts are exhausted. -pub fn retry_with_backoff( - policy: &RetryPolicy, - mut operation: impl FnMut() -> Result, -) -> Result { - let mut attempt = 0; - loop { - match operation() { - Ok(value) => return Ok(value), - Err(err) => { - attempt += 1; - if attempt >= policy.max_attempts { - return Err(err); - } - let _delay = policy.delay_for_attempt(attempt); - } - } - } -} diff --git a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/context_eval_project/src/storage/config_store.rs b/crates/tracedecay-query/assets/runtime-root/tests/fixtures/context_eval_project/src/storage/config_store.rs deleted file mode 100644 index 800d358f9e..0000000000 --- a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/context_eval_project/src/storage/config_store.rs +++ /dev/null @@ -1,42 +0,0 @@ -//! Disk-backed configuration storage: reads and writes a config file. - -use std::collections::HashMap; - -use crate::storage::KeyValueStore; - -/// Reads and writes configuration key/value pairs to a file on disk. -pub struct ConfigStore { - path: String, - values: HashMap, -} - -impl ConfigStore { - pub fn new(path: &str) -> Self { - ConfigStore { - path: path.to_string(), - values: HashMap::new(), - } - } - - /// Reads the full config file contents from disk. - pub fn read_config(&self) -> Result { - std::fs::read_to_string(&self.path).map_err(|err| err.to_string()) - } - - /// Writes a single key/value pair to the config file on disk. This is - /// the entry point for "who writes to the config file" style questions. - pub fn write_config(&mut self, key: &str, value: &str) -> Result<(), String> { - self.write_value(key, value); - std::fs::write(&self.path, format!("{key}={value}\n")).map_err(|err| err.to_string()) - } -} - -impl KeyValueStore for ConfigStore { - fn write_value(&mut self, key: &str, value: &str) { - self.values.insert(key.to_string(), value.to_string()); - } - - fn read_value(&self, key: &str) -> Option { - self.values.get(key).cloned() - } -} diff --git a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/sample.dockerfile b/crates/tracedecay-query/assets/runtime-root/tests/fixtures/sample.dockerfile deleted file mode 100644 index 7c85b20b09..0000000000 --- a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/sample.dockerfile +++ /dev/null @@ -1,37 +0,0 @@ -# Stage 1: Build -FROM rust:1.78-slim AS builder - -ARG APP_VERSION=1.0.0 -ENV CARGO_HOME=/usr/local/cargo - -WORKDIR /app - -COPY Cargo.toml Cargo.lock ./ -COPY src/ ./src/ - -RUN apt-get update && apt-get install -y pkg-config libssl-dev \ - && cargo build --release - -EXPOSE 8080 - -# Stage 2: Runtime -FROM debian:bookworm-slim AS runtime - -LABEL maintainer="dev@example.com" -LABEL version="${APP_VERSION}" - -ENV APP_PORT=8080 -ENV LOG_LEVEL=info - -RUN apt-get update && apt-get install -y ca-certificates \ - && rm -rf /var/lib/apt/lists/* - -COPY --from=builder /app/target/release/myapp /usr/local/bin/myapp - -HEALTHCHECK --interval=30s --timeout=3s \ - CMD curl -f http://localhost:8080/health || exit 1 - -USER nobody - -ENTRYPOINT ["myapp"] -CMD ["--port", "8080"] diff --git a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/cargo-slot/src/main.rust.fixture b/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/cargo-slot/src/main.rust.fixture deleted file mode 100644 index f89ad50f6d..0000000000 --- a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/cargo-slot/src/main.rust.fixture +++ /dev/null @@ -1,6 +0,0 @@ -use std::path::{Path, PathBuf}; - -// Sanitized fixture preserving the authorized cargo-slot symbol contract. -fn tmpfs_scratch_path(slot: &Path) -> PathBuf { - PathBuf::from(slot) -} diff --git a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/integration.rs b/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/integration.rs deleted file mode 100644 index 098f3bd1e7..0000000000 --- a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/integration.rs +++ /dev/null @@ -1,652 +0,0 @@ -//! Host-neutral integration catalog contracts. -//! -//! This module records only the PR6 capability model and fixture-backed host -//! availability. Host artifact rendering, lifecycle operations, remote -//! transport, and host-local durable state belong to later delivery slices. - -use std::collections::BTreeSet; - -use serde::{Deserialize, Serialize}; -use sha2::{Digest, Sha256}; -use thiserror::Error; - -use crate::{CapabilityId, DomainError, canonical_json_bytes}; - -pub const HOST_INTEGRATION_CATALOG_SCHEMA_VERSION_V1: u16 = 1; -const OBSERVATION_CAPTURE_CAPABILITY_ID: &str = "capability.integration.observation.capture"; - -/// Canonical stock host surfaces shared by catalog, packaging, delivery, and -/// conformance consumers. A host surface is not itself evidence that the PR6 -/// observation-capture capability is fixture-backed. -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(rename_all = "snake_case")] -pub enum HostKindV1 { - ClaudeCode, - CursorDesktop, - CursorCloud, - Codex, - Hermes, - Kiro, - ClineFamily, - Cline, - RooCode, - Kilo, - KimiCode, - OpenCode, -} - -impl HostKindV1 { - pub const ALL: [Self; 12] = [ - Self::ClaudeCode, - Self::CursorDesktop, - Self::CursorCloud, - Self::Codex, - Self::Hermes, - Self::Kiro, - Self::ClineFamily, - Self::Cline, - Self::RooCode, - Self::Kilo, - Self::KimiCode, - Self::OpenCode, - ]; - - /// Project a stock host surface into the bounded PR6 observation catalog - /// only when a checked-in native event fixture proves that integration. - pub const fn fixture_backed_observation_integration_id(self) -> Option { - match self { - Self::ClaudeCode => Some(HostIntegrationIdV1::Claude), - Self::CursorDesktop => Some(HostIntegrationIdV1::Cursor), - Self::Codex => Some(HostIntegrationIdV1::Codex), - Self::Hermes => Some(HostIntegrationIdV1::Hermes), - Self::Kiro => Some(HostIntegrationIdV1::Kiro), - Self::CursorCloud - | Self::ClineFamily - | Self::Cline - | Self::RooCode - | Self::Kilo - | Self::KimiCode - | Self::OpenCode => None, - } - } -} - -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] -#[serde(rename_all = "snake_case")] -pub enum HostCapabilityV1 { - Lsp, - NativeDiagnostics, - Hooks, - Mcp, - Cli, -} - -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)] -#[serde(rename_all = "snake_case")] -pub enum HostCapabilityUnavailableReasonV1 { - HostApiAbsent, - HostRegistrationUnsupported, - NativeFixtureLimited, - CheckedInEvidenceMissing, - CompetingExtensionClaim, -} - -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)] -#[serde(tag = "state", content = "reason", rename_all = "snake_case")] -pub enum HostCapabilityStateV1 { - Supported, - Degraded(HostCapabilityUnavailableReasonV1), - Unavailable(HostCapabilityUnavailableReasonV1), -} - -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)] -#[serde(deny_unknown_fields)] -pub struct HostCapabilityRecordV1 { - pub capability: HostCapabilityV1, - pub state: HostCapabilityStateV1, -} - -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] -#[serde(deny_unknown_fields)] -pub struct StockHostCapabilityViewV1 { - host: HostKindV1, - capabilities: [HostCapabilityRecordV1; 5], -} - -impl StockHostCapabilityViewV1 { - pub const fn host(&self) -> HostKindV1 { - self.host - } - - pub const fn capabilities(&self) -> &[HostCapabilityRecordV1; 5] { - &self.capabilities - } -} - -const fn canonical_stock_host_capabilities(host: HostKindV1) -> [HostCapabilityRecordV1; 5] { - use HostCapabilityStateV1::{Degraded, Supported, Unavailable}; - use HostCapabilityUnavailableReasonV1::{ - CheckedInEvidenceMissing, HostApiAbsent, HostRegistrationUnsupported, NativeFixtureLimited, - }; - use HostCapabilityV1::{Cli, Hooks, Lsp, Mcp, NativeDiagnostics}; - - let (lsp, native_diagnostics, hooks) = match host { - HostKindV1::ClaudeCode => (Supported, Unavailable(HostApiAbsent), Supported), - HostKindV1::CursorDesktop => ( - Unavailable(HostRegistrationUnsupported), - Supported, - Supported, - ), - HostKindV1::CursorCloud => ( - Unavailable(HostRegistrationUnsupported), - Unavailable(HostApiAbsent), - Unavailable(CheckedInEvidenceMissing), - ), - HostKindV1::Codex | HostKindV1::Hermes => ( - Unavailable(HostRegistrationUnsupported), - Unavailable(HostApiAbsent), - Supported, - ), - HostKindV1::Kiro => ( - Unavailable(HostRegistrationUnsupported), - Unavailable(HostApiAbsent), - Degraded(NativeFixtureLimited), - ), - HostKindV1::ClineFamily | HostKindV1::Cline | HostKindV1::RooCode | HostKindV1::Kilo => ( - Unavailable(HostRegistrationUnsupported), - Unavailable(HostApiAbsent), - Unavailable(HostApiAbsent), - ), - HostKindV1::KimiCode => ( - Unavailable(HostRegistrationUnsupported), - Unavailable(HostApiAbsent), - Supported, - ), - HostKindV1::OpenCode => (Supported, Supported, Supported), - }; - [ - HostCapabilityRecordV1 { - capability: Lsp, - state: lsp, - }, - HostCapabilityRecordV1 { - capability: NativeDiagnostics, - state: native_diagnostics, - }, - HostCapabilityRecordV1 { - capability: Hooks, - state: hooks, - }, - HostCapabilityRecordV1 { - capability: Mcp, - state: Supported, - }, - HostCapabilityRecordV1 { - capability: Cli, - state: Supported, - }, - ] -} - -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(rename_all = "snake_case")] -#[non_exhaustive] -pub enum HostIntegrationIdV1 { - /// Claude Code's provider identifier remains `claude` for compatibility. - Claude, - Codex, - Cursor, - Hermes, - Kiro, -} - -impl HostIntegrationIdV1 { - pub const ALL: [Self; 5] = [ - Self::Claude, - Self::Codex, - Self::Cursor, - Self::Hermes, - Self::Kiro, - ]; - - pub const fn as_str(self) -> &'static str { - match self { - Self::Claude => "claude", - Self::Codex => "codex", - Self::Cursor => "cursor", - Self::Hermes => "hermes", - Self::Kiro => "kiro", - } - } - - /// Stable host identifier used by hook, daemon, and telemetry adapters. - pub const fn as_wire(self) -> &'static str { - self.as_str() - } - - /// Stable host identifier used by analytics dimensions. - pub const fn as_key(self) -> &'static str { - self.as_str() - } - - pub fn from_wire(value: &str) -> Option { - match value { - "claude" => Some(Self::Claude), - "codex" => Some(Self::Codex), - "cursor" => Some(Self::Cursor), - "hermes" => Some(Self::Hermes), - "kiro" => Some(Self::Kiro), - _ => None, - } - } - - /// Marker used to debounce this host's incremental project syncs. - pub const fn sync_marker_file(self) -> &'static str { - match self { - Self::Claude => ".claude_post_tool_sync_at", - Self::Codex => ".codex_shell_sync_at", - Self::Cursor => ".cursor_shell_sync_at", - Self::Hermes => ".hermes_terminal_receipt_at", - Self::Kiro => ".kiro_post_tool_sync_at", - } - } -} - -/// Every host integration, including every Hermes profile, binds this one -/// user-owned TraceDecay profile. Hosts never select storage or memory scope. -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)] -#[serde(rename_all = "snake_case")] -#[non_exhaustive] -pub enum TraceDecayProfileBindingV1 { - User, -} - -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)] -#[serde(rename_all = "snake_case")] -#[non_exhaustive] -pub enum IntegrationEffectClassV1 { - DaemonWrite, -} - -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)] -#[serde(rename_all = "snake_case")] -#[non_exhaustive] -pub enum IntegrationPrivacyClassV1 { - SensitiveInputSanitizedByDaemon, -} - -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)] -#[serde(rename_all = "snake_case")] -#[non_exhaustive] -pub enum IntegrationDaemonApiV1 { - HostAdmission, -} - -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)] -#[serde(rename_all = "snake_case")] -#[non_exhaustive] -pub enum IntegrationDaemonActionV1 { - CaptureObservation, -} - -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)] -#[serde(deny_unknown_fields)] -pub struct IntegrationDaemonRequirementV1 { - api: IntegrationDaemonApiV1, - action: IntegrationDaemonActionV1, -} - -impl IntegrationDaemonRequirementV1 { - pub const fn new(api: IntegrationDaemonApiV1, action: IntegrationDaemonActionV1) -> Self { - Self { api, action } - } - - pub const fn api(&self) -> IntegrationDaemonApiV1 { - self.api - } - - pub const fn action(&self) -> IntegrationDaemonActionV1 { - self.action - } -} - -/// Bounded reasons proven by the PR6 native host-event fixtures. -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] -#[serde(rename_all = "snake_case")] -#[non_exhaustive] -pub enum HostCapabilityReasonV1 { - SpoolRecordTooLarge, - AuthorityUnavailable, -} - -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] -#[serde( - tag = "status", - content = "reason_code", - rename_all = "snake_case", - deny_unknown_fields -)] -#[non_exhaustive] -pub enum HostCapabilityAvailabilityV1 { - Supported, - Degraded(HostCapabilityReasonV1), - Unavailable(HostCapabilityReasonV1), -} - -impl HostCapabilityAvailabilityV1 { - /// Legal outcomes proven by every PR6 native host-event fixture. - pub const FIXTURE_BACKED_STATES: [Self; 3] = [ - Self::Supported, - Self::Degraded(HostCapabilityReasonV1::SpoolRecordTooLarge), - Self::Unavailable(HostCapabilityReasonV1::AuthorityUnavailable), - ]; -} - -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] -#[serde(deny_unknown_fields)] -pub struct HostCapabilityViewV1 { - integration_id: HostIntegrationIdV1, - profile_binding: TraceDecayProfileBindingV1, - availability_states: Vec, -} - -impl HostCapabilityViewV1 { - pub fn new( - integration_id: HostIntegrationIdV1, - profile_binding: TraceDecayProfileBindingV1, - availability_states: Vec, - ) -> Self { - Self { - integration_id, - profile_binding, - availability_states, - } - } - - pub const fn integration_id(&self) -> HostIntegrationIdV1 { - self.integration_id - } - - pub const fn profile_binding(&self) -> TraceDecayProfileBindingV1 { - self.profile_binding - } - - pub fn availability_states(&self) -> &[HostCapabilityAvailabilityV1] { - &self.availability_states - } -} - -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] -#[serde(deny_unknown_fields)] -pub struct IntegrationCapabilityV1 { - capability_id: CapabilityId, - effect_class: IntegrationEffectClassV1, - privacy_class: IntegrationPrivacyClassV1, - required_daemon: IntegrationDaemonRequirementV1, - hosts: Vec, -} - -impl IntegrationCapabilityV1 { - pub fn capability_id(&self) -> &CapabilityId { - &self.capability_id - } - - pub const fn effect_class(&self) -> IntegrationEffectClassV1 { - self.effect_class - } - - pub const fn privacy_class(&self) -> IntegrationPrivacyClassV1 { - self.privacy_class - } - - pub const fn required_daemon(&self) -> &IntegrationDaemonRequirementV1 { - &self.required_daemon - } - - pub fn hosts(&self) -> &[HostCapabilityViewV1] { - &self.hosts - } -} - -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] -#[serde(deny_unknown_fields)] -pub struct HostIntegrationCatalogV1 { - schema_version: u16, - capabilities: Vec, -} - -impl HostIntegrationCatalogV1 { - pub const fn schema_version(&self) -> u16 { - self.schema_version - } - - pub fn capabilities(&self) -> &[IntegrationCapabilityV1] { - &self.capabilities - } - - pub fn stock_host_capabilities(&self, host: HostKindV1) -> &[HostCapabilityRecordV1; 5] { - match host { - HostKindV1::ClaudeCode => &STOCK_HOST_CAPABILITIES[0], - HostKindV1::CursorDesktop => &STOCK_HOST_CAPABILITIES[1], - HostKindV1::CursorCloud => &STOCK_HOST_CAPABILITIES[2], - HostKindV1::Codex => &STOCK_HOST_CAPABILITIES[3], - HostKindV1::Hermes => &STOCK_HOST_CAPABILITIES[4], - HostKindV1::Kiro => &STOCK_HOST_CAPABILITIES[5], - HostKindV1::ClineFamily => &STOCK_HOST_CAPABILITIES[6], - HostKindV1::Cline => &STOCK_HOST_CAPABILITIES[7], - HostKindV1::RooCode => &STOCK_HOST_CAPABILITIES[8], - HostKindV1::Kilo => &STOCK_HOST_CAPABILITIES[9], - HostKindV1::KimiCode => &STOCK_HOST_CAPABILITIES[10], - HostKindV1::OpenCode => &STOCK_HOST_CAPABILITIES[11], - } - } - - pub fn stock_host_capability_views(&self) -> Vec { - HostKindV1::ALL - .into_iter() - .map(|host| StockHostCapabilityViewV1 { - host, - capabilities: *self.stock_host_capabilities(host), - }) - .collect() - } - - /// Canonical bytes for the complete catalog authority: the bounded PR6 - /// observation fixture matrix plus every stock host surface capability. - pub fn canonical_authority_bytes(&self) -> Result, DomainError> { - canonical_json_bytes(&HostIntegrationCatalogAuthorityPayloadV1 { - observation_catalog: self, - stock_hosts: self.stock_host_capability_views(), - }) - } - - pub fn canonical_authority_digest(&self) -> Result<[u8; 32], DomainError> { - self.canonical_authority_bytes() - .map(|bytes| Sha256::digest(bytes).into()) - } - - /// Canonical per-host projection pinned into embedded bundle manifests. - pub fn host_capability_digest(&self, host: HostKindV1) -> Result<[u8; 32], DomainError> { - canonical_json_bytes(&StockHostCapabilityViewV1 { - host, - capabilities: *self.stock_host_capabilities(host), - }) - .map(|bytes| Sha256::digest(bytes).into()) - } - - pub fn validate(&self) -> Result<(), IntegrationCatalogError> { - if self.schema_version != HOST_INTEGRATION_CATALOG_SCHEMA_VERSION_V1 { - return Err(IntegrationCatalogError::UnsupportedSchemaVersion( - self.schema_version, - )); - } - if self.capabilities.is_empty() { - return Err(IntegrationCatalogError::EmptyCatalog); - } - - let required_states = HostCapabilityAvailabilityV1::FIXTURE_BACKED_STATES - .into_iter() - .collect::>(); - let required_hosts = HostIntegrationIdV1::ALL - .into_iter() - .collect::>(); - let mut capability_ids = BTreeSet::new(); - for capability in &self.capabilities { - capability.capability_id.validate().map_err(|_| { - IntegrationCatalogError::InvalidCapabilityId( - capability.capability_id.as_str().to_owned(), - ) - })?; - if !capability_ids.insert(capability.capability_id.as_str()) { - return Err(IntegrationCatalogError::DuplicateCapabilityId( - capability.capability_id.as_str().to_owned(), - )); - } - if capability.hosts.is_empty() { - return Err(IntegrationCatalogError::EmptyHostMatrix( - capability.capability_id.as_str().to_owned(), - )); - } - - let mut integration_ids = BTreeSet::new(); - for host in &capability.hosts { - if !integration_ids.insert(host.integration_id) { - return Err(IntegrationCatalogError::DuplicateHostIntegration { - capability_id: capability.capability_id.as_str().to_owned(), - integration_id: host.integration_id, - }); - } - - let mut availability_states = BTreeSet::new(); - for state in &host.availability_states { - if !availability_states.insert(*state) { - return Err(IntegrationCatalogError::DuplicateHostAvailabilityState { - capability_id: capability.capability_id.as_str().to_owned(), - integration_id: host.integration_id, - state: *state, - }); - } - } - if availability_states != required_states { - return Err(IntegrationCatalogError::InvalidHostAvailabilityStates { - capability_id: capability.capability_id.as_str().to_owned(), - integration_id: host.integration_id, - missing: required_states - .difference(&availability_states) - .copied() - .collect(), - unexpected: availability_states - .difference(&required_states) - .copied() - .collect(), - }); - } - } - if integration_ids != required_hosts { - return Err(IntegrationCatalogError::IncompleteHostMatrix { - capability_id: capability.capability_id.as_str().to_owned(), - missing: required_hosts - .difference(&integration_ids) - .copied() - .collect(), - }); - } - } - Ok(()) - } -} - -const STOCK_HOST_CAPABILITIES: [[HostCapabilityRecordV1; 5]; 12] = [ - canonical_stock_host_capabilities(HostKindV1::ClaudeCode), - canonical_stock_host_capabilities(HostKindV1::CursorDesktop), - canonical_stock_host_capabilities(HostKindV1::CursorCloud), - canonical_stock_host_capabilities(HostKindV1::Codex), - canonical_stock_host_capabilities(HostKindV1::Hermes), - canonical_stock_host_capabilities(HostKindV1::Kiro), - canonical_stock_host_capabilities(HostKindV1::ClineFamily), - canonical_stock_host_capabilities(HostKindV1::Cline), - canonical_stock_host_capabilities(HostKindV1::RooCode), - canonical_stock_host_capabilities(HostKindV1::Kilo), - canonical_stock_host_capabilities(HostKindV1::KimiCode), - canonical_stock_host_capabilities(HostKindV1::OpenCode), -]; - -#[derive(Serialize)] -struct HostIntegrationCatalogAuthorityPayloadV1<'a> { - observation_catalog: &'a HostIntegrationCatalogV1, - stock_hosts: Vec, -} - -pub fn stock_host_capabilities(host: HostKindV1) -> [HostCapabilityRecordV1; 5] { - *host_integration_catalog_v1().stock_host_capabilities(host) -} - -#[derive(Clone, Debug, Error, PartialEq, Eq)] -#[non_exhaustive] -pub enum IntegrationCatalogError { - #[error("unsupported host integration catalog schema version {0}")] - UnsupportedSchemaVersion(u16), - #[error("host integration catalog must define at least one capability")] - EmptyCatalog, - #[error("invalid capability id `{0}`")] - InvalidCapabilityId(String), - #[error("duplicate capability id `{0}`")] - DuplicateCapabilityId(String), - #[error("capability `{0}` must define a host matrix")] - EmptyHostMatrix(String), - #[error("capability `{capability_id}` repeats host integration `{integration_id:?}`")] - DuplicateHostIntegration { - capability_id: String, - integration_id: HostIntegrationIdV1, - }, - #[error("capability `{capability_id}` omits required host integrations {missing:?}")] - IncompleteHostMatrix { - capability_id: String, - missing: Vec, - }, - #[error( - "capability `{capability_id}` repeats availability state {state:?} for host integration `{integration_id:?}`" - )] - DuplicateHostAvailabilityState { - capability_id: String, - integration_id: HostIntegrationIdV1, - state: HostCapabilityAvailabilityV1, - }, - #[error( - "capability `{capability_id}` has invalid availability states for host integration `{integration_id:?}` (missing {missing:?}, unexpected {unexpected:?})" - )] - InvalidHostAvailabilityStates { - capability_id: String, - integration_id: HostIntegrationIdV1, - missing: Vec, - unexpected: Vec, - }, -} - -pub fn host_integration_catalog_v1() -> HostIntegrationCatalogV1 { - let hosts = HostIntegrationIdV1::ALL - .into_iter() - .map(|integration_id| { - HostCapabilityViewV1::new( - integration_id, - TraceDecayProfileBindingV1::User, - HostCapabilityAvailabilityV1::FIXTURE_BACKED_STATES.to_vec(), - ) - }) - .collect(); - let capability = IntegrationCapabilityV1 { - capability_id: CapabilityId::new(OBSERVATION_CAPTURE_CAPABILITY_ID) - .expect("built-in integration capability id is valid"), - effect_class: IntegrationEffectClassV1::DaemonWrite, - privacy_class: IntegrationPrivacyClassV1::SensitiveInputSanitizedByDaemon, - required_daemon: IntegrationDaemonRequirementV1::new( - IntegrationDaemonApiV1::HostAdmission, - IntegrationDaemonActionV1::CaptureObservation, - ), - hosts, - }; - HostIntegrationCatalogV1 { - schema_version: HOST_INTEGRATION_CATALOG_SCHEMA_VERSION_V1, - capabilities: vec![capability], - } -} diff --git a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/repository.rs b/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/repository.rs deleted file mode 100644 index 816ce1a55f..0000000000 --- a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/repository.rs +++ /dev/null @@ -1,639 +0,0 @@ -//! Pure repository-provenance contracts. -//! -//! Capture happens outside this crate. These values preserve only canonical, -//! path-safe evidence and never infer facts that the capture boundary could -//! not establish. - -use serde::{Deserialize, Deserializer, Serialize}; - -use crate::observation::CanonicalObservationIdV1; -use crate::research::{ - CommitId, DomainError, PrivacyDomainBoundLocatorDigest, ProjectId, ProjectionGenerationId, - RefId, RepositoryCaptureId, RepositoryId, TreeId, UtcMicros, WorktreeId, canonical_sha256, -}; - -const CAPTURE_ID_NAMESPACE: &str = "repository.capture.v1"; - -/// Explicit availability of one repository evidence value. -#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde( - tag = "availability", - content = "value", - rename_all = "snake_case", - deny_unknown_fields -)] -pub enum EvidenceAvailabilityV1 { - Known(T), - Missing, - Unborn, - Detached, - Conflicted, - PartiallyReadable(T), - Unsupported, - Unavailable, - #[default] - Unknown, -} - -impl EvidenceAvailabilityV1 { - pub fn value(&self) -> Option<&T> { - match self { - Self::Known(value) | Self::PartiallyReadable(value) => Some(value), - Self::Missing - | Self::Unborn - | Self::Detached - | Self::Conflicted - | Self::Unsupported - | Self::Unavailable - | Self::Unknown => None, - } - } - - fn validate_with( - &self, - validate: impl FnOnce(&T) -> Result<(), DomainError>, - ) -> Result<(), DomainError> { - match self.value() { - Some(value) => validate(value), - None => Ok(()), - } - } -} - -/// Repository working-state evidence when it was observable. -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(rename_all = "snake_case")] -pub enum RepositoryDirtyStateV1 { - Clean, - Dirty, - Conflicted, -} - -/// Privacy-safe identity of the configured primary repository remote. -/// -/// The captured digest never contains a URL, credential, query, or fragment. -/// `Missing`, `Invalid`, and `Oversized` stay distinct so callers do not infer -/// that a remote was available when the bounded probe could not retain one. -#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde( - tag = "availability", - content = "value", - rename_all = "snake_case", - deny_unknown_fields -)] -pub enum RepositoryRemoteIdentityV1 { - Known(PrivacyDomainBoundLocatorDigest), - Missing, - Invalid, - Oversized, - Unavailable, - #[default] - Unknown, -} - -impl RepositoryRemoteIdentityV1 { - pub fn digest(&self) -> Option<&PrivacyDomainBoundLocatorDigest> { - match self { - Self::Known(digest) => Some(digest), - Self::Missing | Self::Invalid | Self::Oversized | Self::Unavailable | Self::Unknown => { - None - } - } - } - - pub const fn is_unknown(&self) -> bool { - matches!(self, Self::Unknown) - } - - fn validate(&self) -> Result<(), DomainError> { - self.digest() - .map_or(Ok(()), PrivacyDomainBoundLocatorDigest::validate) - } -} - -/// Bounded repository facts captured by the daemon/application boundary. -#[derive(Clone, Debug, Serialize, PartialEq, Eq)] -#[serde(deny_unknown_fields)] -pub struct RepositoryEvidenceV1 { - attached_ref: EvidenceAvailabilityV1, - head_commit: EvidenceAvailabilityV1, - index_tree: EvidenceAvailabilityV1, - path_identity_digest: EvidenceAvailabilityV1, - #[serde( - default, - skip_serializing_if = "RepositoryRemoteIdentityV1::is_unknown" - )] - remote_identity: RepositoryRemoteIdentityV1, - dirty_state: EvidenceAvailabilityV1, -} - -#[derive(Deserialize)] -#[serde(deny_unknown_fields)] -struct RepositoryEvidenceWireV1 { - attached_ref: EvidenceAvailabilityV1, - head_commit: EvidenceAvailabilityV1, - index_tree: EvidenceAvailabilityV1, - path_identity_digest: EvidenceAvailabilityV1, - #[serde(default)] - remote_identity: RepositoryRemoteIdentityV1, - dirty_state: EvidenceAvailabilityV1, -} - -impl<'de> Deserialize<'de> for RepositoryEvidenceV1 { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let wire = RepositoryEvidenceWireV1::deserialize(deserializer)?; - Self::new( - wire.attached_ref, - wire.head_commit, - wire.index_tree, - wire.path_identity_digest, - wire.remote_identity, - wire.dirty_state, - ) - .map_err(serde::de::Error::custom) - } -} - -impl RepositoryEvidenceV1 { - pub fn new( - attached_ref: EvidenceAvailabilityV1, - head_commit: EvidenceAvailabilityV1, - index_tree: EvidenceAvailabilityV1, - path_identity_digest: EvidenceAvailabilityV1, - remote_identity: RepositoryRemoteIdentityV1, - dirty_state: EvidenceAvailabilityV1, - ) -> Result { - let evidence = Self { - attached_ref, - head_commit, - index_tree, - path_identity_digest, - remote_identity, - dirty_state, - }; - evidence.validate()?; - Ok(evidence) - } - - pub fn attached_ref(&self) -> &EvidenceAvailabilityV1 { - &self.attached_ref - } - - pub fn head_commit(&self) -> &EvidenceAvailabilityV1 { - &self.head_commit - } - - pub fn index_tree(&self) -> &EvidenceAvailabilityV1 { - &self.index_tree - } - - pub fn path_identity_digest(&self) -> &EvidenceAvailabilityV1 { - &self.path_identity_digest - } - - pub fn remote_identity(&self) -> &RepositoryRemoteIdentityV1 { - &self.remote_identity - } - - pub fn dirty_state(&self) -> &EvidenceAvailabilityV1 { - &self.dirty_state - } - - pub fn validate(&self) -> Result<(), DomainError> { - self.attached_ref.validate_with(RefId::validate)?; - self.head_commit.validate_with(|value| { - value.validate()?; - validate_git_object_id(value.as_str(), "HEAD commit") - })?; - self.index_tree.validate_with(|value| { - value.validate()?; - validate_git_object_id(value.as_str(), "index tree") - })?; - self.path_identity_digest - .validate_with(PrivacyDomainBoundLocatorDigest::validate)?; - self.remote_identity.validate()?; - Ok(()) - } -} - -/// One immutable, path-safe capture of repository identity and state. -#[derive(Clone, Debug, Serialize, PartialEq, Eq)] -#[serde(deny_unknown_fields)] -pub struct RepositoryProvenanceV1 { - capture_id: RepositoryCaptureId, - repository_id: RepositoryId, - #[serde(default, skip_serializing_if = "Option::is_none")] - project_id: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - worktree_id: Option, - canonical_root_digest: PrivacyDomainBoundLocatorDigest, - evidence: RepositoryEvidenceV1, - captured_at: UtcMicros, -} - -impl RepositoryProvenanceV1 { - pub fn new( - repository_id: RepositoryId, - project_id: Option, - worktree_id: Option, - canonical_root_digest: PrivacyDomainBoundLocatorDigest, - evidence: RepositoryEvidenceV1, - captured_at: UtcMicros, - ) -> Result { - repository_id.validate()?; - if let Some(project_id) = &project_id { - project_id.validate()?; - } - if let Some(worktree_id) = &worktree_id { - worktree_id.validate()?; - } - canonical_root_digest.validate()?; - evidence.validate()?; - - let capture_id = derive_capture_id( - &repository_id, - project_id.as_ref(), - worktree_id.as_ref(), - &canonical_root_digest, - &evidence, - captured_at, - )?; - Ok(Self { - capture_id, - repository_id, - project_id, - worktree_id, - canonical_root_digest, - evidence, - captured_at, - }) - } - - pub fn capture_id(&self) -> &RepositoryCaptureId { - &self.capture_id - } - - pub fn repository_id(&self) -> &RepositoryId { - &self.repository_id - } - - pub fn project_id(&self) -> Option<&ProjectId> { - self.project_id.as_ref() - } - - pub fn worktree_id(&self) -> Option<&WorktreeId> { - self.worktree_id.as_ref() - } - - pub fn canonical_root_digest(&self) -> &PrivacyDomainBoundLocatorDigest { - &self.canonical_root_digest - } - - pub fn evidence(&self) -> &RepositoryEvidenceV1 { - &self.evidence - } - - pub fn captured_at(&self) -> UtcMicros { - self.captured_at - } - - pub fn validate(&self) -> Result<(), DomainError> { - let expected = derive_capture_id( - &self.repository_id, - self.project_id.as_ref(), - self.worktree_id.as_ref(), - &self.canonical_root_digest, - &self.evidence, - self.captured_at, - )?; - if self.capture_id != expected { - return Err(DomainError::SnapshotMismatch { - field: "repository capture identity", - }); - } - Ok(()) - } -} - -#[derive(Deserialize)] -#[serde(deny_unknown_fields)] -struct RepositoryProvenanceWireV1 { - capture_id: RepositoryCaptureId, - repository_id: RepositoryId, - #[serde(default)] - project_id: Option, - #[serde(default)] - worktree_id: Option, - canonical_root_digest: PrivacyDomainBoundLocatorDigest, - evidence: RepositoryEvidenceV1, - captured_at: UtcMicros, -} - -impl<'de> Deserialize<'de> for RepositoryProvenanceV1 { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let wire = RepositoryProvenanceWireV1::deserialize(deserializer)?; - let capture = Self::new( - wire.repository_id, - wire.project_id, - wire.worktree_id, - wire.canonical_root_digest, - wire.evidence, - wire.captured_at, - ) - .map_err(serde::de::Error::custom)?; - if wire.capture_id != capture.capture_id { - return Err(serde::de::Error::custom( - "repository capture identity does not match canonical evidence", - )); - } - Ok(capture) - } -} - -/// Repository capture pinned to one immutable projection generation. -#[derive(Clone, Debug, Serialize, PartialEq, Eq)] -#[serde(deny_unknown_fields)] -pub struct GenerationBoundRepositoryProvenanceV1 { - generation_id: ProjectionGenerationId, - capture_id: RepositoryCaptureId, - capture: RepositoryProvenanceV1, - #[serde(default, skip_serializing_if = "Option::is_none")] - source_observation: Option, -} - -impl GenerationBoundRepositoryProvenanceV1 { - pub fn new( - generation_id: ProjectionGenerationId, - capture: RepositoryProvenanceV1, - source_observation: Option, - ) -> Result { - generation_id.validate()?; - capture.validate()?; - Ok(Self { - generation_id, - capture_id: capture.capture_id.clone(), - capture, - source_observation, - }) - } - - pub fn generation_id(&self) -> &ProjectionGenerationId { - &self.generation_id - } - - pub fn capture_id(&self) -> &RepositoryCaptureId { - &self.capture_id - } - - pub fn capture(&self) -> &RepositoryProvenanceV1 { - &self.capture - } - - pub fn source_observation(&self) -> Option<&CanonicalObservationIdV1> { - self.source_observation.as_ref() - } - - pub fn validate(&self) -> Result<(), DomainError> { - self.generation_id.validate()?; - self.capture.validate()?; - if self.capture_id != self.capture.capture_id { - return Err(DomainError::SnapshotMismatch { - field: "generation repository capture identity", - }); - } - Ok(()) - } -} - -#[derive(Deserialize)] -#[serde(deny_unknown_fields)] -struct GenerationBoundRepositoryProvenanceWireV1 { - generation_id: ProjectionGenerationId, - capture_id: RepositoryCaptureId, - capture: RepositoryProvenanceV1, - #[serde(default)] - source_observation: Option, -} - -impl<'de> Deserialize<'de> for GenerationBoundRepositoryProvenanceV1 { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let wire = GenerationBoundRepositoryProvenanceWireV1::deserialize(deserializer)?; - let binding = Self::new(wire.generation_id, wire.capture, wire.source_observation) - .map_err(serde::de::Error::custom)?; - if wire.capture_id != binding.capture_id { - return Err(serde::de::Error::custom( - "generation binding capture identity does not match its capture", - )); - } - Ok(binding) - } -} - -#[derive(Serialize)] -struct RepositoryCaptureIdentityMaterialV1<'a> { - repository_id: &'a RepositoryId, - project_id: Option<&'a ProjectId>, - worktree_id: Option<&'a WorktreeId>, - canonical_root_digest: &'a PrivacyDomainBoundLocatorDigest, - evidence: &'a RepositoryEvidenceV1, - captured_at: UtcMicros, -} - -fn derive_capture_id( - repository_id: &RepositoryId, - project_id: Option<&ProjectId>, - worktree_id: Option<&WorktreeId>, - canonical_root_digest: &PrivacyDomainBoundLocatorDigest, - evidence: &RepositoryEvidenceV1, - captured_at: UtcMicros, -) -> Result { - let digest = canonical_sha256(&( - CAPTURE_ID_NAMESPACE, - RepositoryCaptureIdentityMaterialV1 { - repository_id, - project_id, - worktree_id, - canonical_root_digest, - evidence, - captured_at, - }, - ))?; - let encoded = digest - .as_str() - .strip_prefix("sha256:") - .ok_or(DomainError::NonCanonical { - field: "repository capture identity digest", - })?; - RepositoryCaptureId::new(format!("{CAPTURE_ID_NAMESPACE}.{encoded}")) -} - -fn validate_git_object_id(value: &str, field: &'static str) -> Result<(), DomainError> { - if matches!(value.len(), 40 | 64) - && value - .bytes() - .all(|byte| byte.is_ascii_digit() || (b'a'..=b'f').contains(&byte)) - { - Ok(()) - } else { - Err(DomainError::NonCanonical { field }) - } -} - -#[cfg(test)] -mod tests { - use serde_json::Value; - - use super::*; - - const DIGEST_A: &str = - "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; - const DIGEST_B: &str = - "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; - const COMMIT: &str = "0123456789abcdef0123456789abcdef01234567"; - const TREE: &str = "89abcdef0123456789abcdef0123456789abcdef"; - - fn id(value: &str) -> T - where - T: TryFrom, - { - T::try_from(value.to_owned()).expect("valid fixture identity") - } - - fn evidence() -> RepositoryEvidenceV1 { - RepositoryEvidenceV1::new( - EvidenceAvailabilityV1::Known(id("refs/heads/main")), - EvidenceAvailabilityV1::Known(id(COMMIT)), - EvidenceAvailabilityV1::Known(id(TREE)), - EvidenceAvailabilityV1::Known(id(DIGEST_B)), - RepositoryRemoteIdentityV1::Known(id(DIGEST_A)), - EvidenceAvailabilityV1::Known(RepositoryDirtyStateV1::Clean), - ) - .unwrap() - } - - fn capture() -> RepositoryProvenanceV1 { - RepositoryProvenanceV1::new( - id("repository.fixture"), - Some(id("project.fixture")), - Some(id("worktree.fixture")), - id(DIGEST_A), - evidence(), - UtcMicros(42), - ) - .unwrap() - } - - #[test] - fn capture_identity_is_deterministic() { - assert_eq!(capture().capture_id(), capture().capture_id()); - } - - #[test] - fn detached_unborn_and_unavailable_are_preserved() { - let evidence = RepositoryEvidenceV1::new( - EvidenceAvailabilityV1::Detached, - EvidenceAvailabilityV1::Unborn, - EvidenceAvailabilityV1::Unavailable, - EvidenceAvailabilityV1::Unknown, - RepositoryRemoteIdentityV1::Unknown, - EvidenceAvailabilityV1::Unknown, - ) - .unwrap(); - let round_trip: RepositoryEvidenceV1 = - serde_json::from_value(serde_json::to_value(&evidence).unwrap()).unwrap(); - - assert_eq!(round_trip.attached_ref(), &EvidenceAvailabilityV1::Detached); - assert_eq!(round_trip.head_commit(), &EvidenceAvailabilityV1::Unborn); - assert_eq!( - round_trip.index_tree(), - &EvidenceAvailabilityV1::Unavailable - ); - assert_eq!( - round_trip.remote_identity(), - &RepositoryRemoteIdentityV1::Unknown - ); - } - - #[test] - fn legacy_unknown_remote_identity_preserves_capture_identity() { - let legacy_evidence = RepositoryEvidenceV1::new( - EvidenceAvailabilityV1::Known(id("refs/heads/main")), - EvidenceAvailabilityV1::Known(id(COMMIT)), - EvidenceAvailabilityV1::Known(id(TREE)), - EvidenceAvailabilityV1::Known(id(DIGEST_B)), - RepositoryRemoteIdentityV1::Unknown, - EvidenceAvailabilityV1::Known(RepositoryDirtyStateV1::Clean), - ) - .unwrap(); - let capture = RepositoryProvenanceV1::new( - id("repository.legacy-fixture"), - Some(id("project.fixture")), - Some(id("worktree.fixture")), - id(DIGEST_A), - legacy_evidence, - UtcMicros(42), - ) - .unwrap(); - let encoded = serde_json::to_value(&capture).unwrap(); - assert!(encoded["evidence"].get("remote_identity").is_none()); - let decoded: RepositoryProvenanceV1 = serde_json::from_value(encoded).unwrap(); - assert_eq!(decoded.capture_id(), capture.capture_id()); - assert_eq!( - decoded.evidence().remote_identity(), - &RepositoryRemoteIdentityV1::Unknown - ); - } - - #[test] - fn standalone_evidence_deserialization_rejects_noncanonical_git_object_ids() { - let mut value = serde_json::to_value(evidence()).unwrap(); - value["head_commit"]["value"] = Value::String("0123456789abcdef".into()); - - assert!(serde_json::from_value::(value).is_err()); - } - - #[test] - fn project_and_worktree_aliases_do_not_define_repository_identity() { - let first = capture(); - let second = RepositoryProvenanceV1::new( - first.repository_id().clone(), - Some(id("project.alias")), - Some(id("worktree.alias")), - first.canonical_root_digest().clone(), - first.evidence().clone(), - first.captured_at(), - ) - .unwrap(); - - assert_eq!(first.repository_id(), second.repository_id()); - assert_ne!(first.capture_id(), second.capture_id()); - } - - #[test] - fn generation_binding_rejects_capture_mismatch_and_tampering() { - let binding = GenerationBoundRepositoryProvenanceV1::new( - id("projection.fixture.v1"), - capture(), - None, - ) - .unwrap(); - let mut mismatched = serde_json::to_value(&binding).unwrap(); - mismatched["capture_id"] = Value::String("repository.capture.v1.invalid".into()); - assert!( - serde_json::from_value::(mismatched).is_err() - ); - - let mut tampered = serde_json::to_value(&binding).unwrap(); - tampered["capture"]["captured_at"] = Value::from(43); - assert!(serde_json::from_value::(tampered).is_err()); - } -} diff --git a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/canonical.rs b/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/canonical.rs deleted file mode 100644 index dafc4ad16b..0000000000 --- a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/canonical.rs +++ /dev/null @@ -1,158 +0,0 @@ -use serde::Serialize; -use serde_json::Value; -use sha2::{Digest, Sha256}; - -use super::error::DomainError; -use super::id::ManifestDigest; - -/// Serialize any domain value to the crate's canonical JSON byte form. -pub fn canonical_json_bytes(value: &T) -> Result, DomainError> { - let value = serde_json::to_value(value) - .map_err(|error| DomainError::CanonicalSerialization(error.to_string()))?; - let mut output = Vec::new(); - write_canonical(&value, &mut output)?; - Ok(output) -} - -/// Serialize a JSON value with recursively lexicographic object keys and no -/// insignificant whitespace. -pub fn canonical_json_value(value: &Value) -> Result { - let mut output = String::new(); - write_canonical(value, &mut output)?; - Ok(output) -} - -/// Compute the canonical SHA-256 digest encoding used by domain manifests. -pub fn canonical_sha256(value: &T) -> Result { - let value = serde_json::to_value(value) - .map_err(|error| DomainError::CanonicalSerialization(error.to_string()))?; - let mut hasher = Sha256::new(); - write_canonical(&value, &mut hasher)?; - let digest = hasher.finalize(); - let mut encoded = String::with_capacity("sha256:".len() + digest.len() * 2); - encoded.push_str("sha256:"); - for byte in digest { - use std::fmt::Write as _; - write!(&mut encoded, "{byte:02x}") - .map_err(|error| DomainError::CanonicalSerialization(error.to_string()))?; - } - ManifestDigest::new(encoded) -} - -trait CanonicalSink { - fn write(&mut self, chunk: &str); -} - -impl CanonicalSink for String { - fn write(&mut self, chunk: &str) { - self.push_str(chunk); - } -} - -impl CanonicalSink for Vec { - fn write(&mut self, chunk: &str) { - self.extend_from_slice(chunk.as_bytes()); - } -} - -impl CanonicalSink for Sha256 { - fn write(&mut self, chunk: &str) { - Digest::update(self, chunk.as_bytes()); - } -} - -fn write_canonical(value: &Value, output: &mut impl CanonicalSink) -> Result<(), DomainError> { - match value { - Value::Null => output.write("null"), - Value::Bool(value) => output.write(if *value { "true" } else { "false" }), - Value::Number(value) => output.write(&value.to_string()), - Value::String(value) => output.write( - &serde_json::to_string(value) - .map_err(|error| DomainError::CanonicalSerialization(error.to_string()))?, - ), - Value::Array(values) => { - output.write("["); - for (index, value) in values.iter().enumerate() { - if index > 0 { - output.write(","); - } - write_canonical(value, output)?; - } - output.write("]"); - } - Value::Object(values) => { - output.write("{"); - let mut entries: Vec<_> = values.iter().collect(); - entries.sort_unstable_by_key(|(key, _)| *key); - for (index, (key, value)) in entries.into_iter().enumerate() { - if index > 0 { - output.write(","); - } - output.write( - &serde_json::to_string(key) - .map_err(|error| DomainError::CanonicalSerialization(error.to_string()))?, - ); - output.write(":"); - write_canonical(value, output)?; - } - output.write("}"); - } - } - Ok(()) -} - -#[cfg(test)] -mod tests { - use serde_json::json; - - use super::*; - - #[test] - fn canonical_outputs_match_for_nested_ordering_and_scalars() { - let value = json!({ - "z": null, - "array": [true, false, -12.5, 0, {"z": 2, "a": 1}], - "a": {"z": "last", "a": "first"}, - }); - let expected = concat!( - r#"{"a":{"a":"first","z":"last"},"#, - r#""array":[true,false,-12.5,0,{"a":1,"z":2}],"#, - r#""z":null}"#, - ); - - let text = canonical_json_value(&value).unwrap(); - let bytes = canonical_json_bytes(&value).unwrap(); - - assert_eq!(text, expected); - assert_eq!(bytes, expected.as_bytes()); - } - - #[test] - fn canonical_outputs_preserve_json_escapes_and_unicode() { - let value = json!({ - "unicode": "雪😀é", - "escaped": "quote: \" slash: \\ newline:\n tab:\t control:\u{0001}", - }); - let expected = "{\"escaped\":\"quote: \\\" slash: \\\\ newline:\\n tab:\\t control:\\u0001\",\"unicode\":\"雪😀é\"}"; - - assert_eq!(canonical_json_value(&value).unwrap(), expected); - assert_eq!(canonical_json_bytes(&value).unwrap(), expected.as_bytes()); - } - - #[test] - fn streaming_digest_matches_digest_of_canonical_bytes() { - let value = json!({ - "unicode": ["雪", "😀", "é"], - "nested": {"z": null, "a": [true, "line\nfeed", 42]}, - }); - let bytes = canonical_json_bytes(&value).unwrap(); - let digest = Sha256::digest(&bytes); - let mut expected = String::from("sha256:"); - for byte in digest { - use std::fmt::Write as _; - write!(&mut expected, "{byte:02x}").unwrap(); - } - - assert_eq!(canonical_sha256(&value).unwrap().as_str(), expected); - } -} diff --git a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/coverage.rs b/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/coverage.rs deleted file mode 100644 index 32f4494ca0..0000000000 --- a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/coverage.rs +++ /dev/null @@ -1,672 +0,0 @@ -use std::collections::BTreeMap; -use std::fmt; -use std::marker::PhantomData; -use std::ops::{Index, IndexMut}; - -use serde::de::{IgnoredAny, SeqAccess, Visitor}; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; - -use super::error::DomainError; -use super::id::{ - AuthorityEpoch, BrainId, BrainNodeId, EntityVersionId, ManifestDigest, ShardId, - StoreAuthorityId, ensure_unique, validate_canonical_string, -}; -use super::time::UtcMicros; -use super::watermark::{ShardWatermark, VectorWatermark}; - -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(rename_all = "snake_case")] -pub enum ShardDispositionV1 { - Searched, - Skipped, - Stale, - Unavailable, - Incompatible, - Locked, - Redacted, - Truncated, -} - -/// Whether the complete shard universe was known when coverage was captured. -#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, PartialEq, Eq)] -#[serde(rename_all = "snake_case")] -pub enum CoverageUniverseKnowledgeV1 { - Known, - #[default] - Unknown, -} - -/// Registry-owned retention class code. The domain records the code without -/// implementing retention policy or storage behavior. -#[derive(Clone, Debug, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(transparent)] -pub struct RetentionClass(String); - -impl RetentionClass { - pub fn new(value: impl Into) -> Result { - let value = value.into(); - validate_canonical_string(&value, "RetentionClass")?; - Ok(Self(value)) - } - - pub fn as_str(&self) -> &str { - &self.0 - } -} - -impl<'de> Deserialize<'de> for RetentionClass { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - Self::new(String::deserialize(deserializer)?).map_err(serde::de::Error::custom) - } -} - -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] -#[serde(deny_unknown_fields)] -pub struct EvidenceRetentionWatermark { - pub evaluated_at: UtcMicros, - pub cutoffs: BTreeMap, -} - -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(rename_all = "snake_case")] -pub enum BrainNodeRoleV1 { - Standalone, - Authority, - RemoteClient, - ReadReplica, - Standby, -} - -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)] -#[serde(rename_all = "snake_case", deny_unknown_fields)] -pub enum ReadConsistencyV1 { - Authoritative, - BoundedStale { max_lag_micros: u64 }, - OfflineCache, -} - -/// Signed cache-grant state plus the authority-side evidence verified for this -/// coverage evaluation. -/// -/// The grant digest identifies the immutable signed snapshot. Its validity and -/// purge frontier are carried directly so freshness cannot be inferred from an -/// unbound cache timestamp. Optional verified fields represent current evidence; -/// absent evidence never implies current placement, authority, or revocation. -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] -#[serde(deny_unknown_fields)] -pub struct VerifiedCacheGrantSnapshotV1 { - pub grant_digest: ManifestDigest, - pub issued_at: UtcMicros, - pub not_after: UtcMicros, - pub grant_revocation_generation: u64, - pub purge_frontier: VectorWatermark, - pub verified_placement_version: Option, - pub verified_authority_id: Option, - pub verified_authority_epoch: Option, - pub verified_revocation_generation: Option, - pub verified_purge_frontier: Option, -} - -impl VerifiedCacheGrantSnapshotV1 { - fn validate(&self) -> Result<(), DomainError> { - self.grant_digest.validate()?; - if self.not_after <= self.issued_at { - return Err(DomainError::NonCanonical { - field: "cache grant validity", - }); - } - for shard in self.purge_frontier.components.keys() { - shard.validate()?; - } - if let Some(verified_purge_frontier) = &self.verified_purge_frontier { - for shard in verified_purge_frontier.components.keys() { - shard.validate()?; - } - } - if let Some(placement_version) = &self.verified_placement_version { - placement_version.validate()?; - } - if let Some(authority_id) = &self.verified_authority_id { - authority_id.validate()?; - } - if self.verified_authority_id.is_some() != self.verified_authority_epoch.is_some() { - return Err(DomainError::UnknownReference { - field: "cache grant verified authority", - }); - } - Ok(()) - } - - fn proves_current_access( - &self, - evaluated_at: UtcMicros, - cache_not_after: UtcMicros, - placement_version: &EntityVersionId, - authority_id: &StoreAuthorityId, - authority_epoch: AuthorityEpoch, - ) -> bool { - self.issued_at <= evaluated_at - && self.not_after == cache_not_after - && self.not_after > evaluated_at - && self.verified_placement_version.as_ref() == Some(placement_version) - && self.verified_authority_id.as_ref() == Some(authority_id) - && self.verified_authority_epoch == Some(authority_epoch) - && self.verified_revocation_generation == Some(self.grant_revocation_generation) - && self - .verified_purge_frontier - .as_ref() - .is_some_and(|verified| verified.dominates(&self.purge_frontier)) - } -} - -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] -#[serde(deny_unknown_fields)] -pub struct RemoteShardCoverageV1 { - pub shard_id: ShardId, - pub authority_id: StoreAuthorityId, - pub authority_epoch: AuthorityEpoch, - pub served_by_node: BrainNodeId, - pub served_by_role: BrainNodeRoleV1, - pub captured_watermark: Option, - pub cache_generation: Option, - pub cache_not_after: Option, - pub cache_age_micros: Option, - pub cache_grant_snapshot: Option, - pub sync_lag_micros: Option, - pub pending_local_observations: u64, - pub pending_tombstone_acks: u64, -} - -impl RemoteShardCoverageV1 { - fn validate(&self) -> Result<(), DomainError> { - self.shard_id.validate()?; - self.authority_id.validate()?; - self.served_by_node.validate()?; - if let Some(watermark) = &self.captured_watermark - && watermark.shard_id != self.shard_id - { - return Err(DomainError::UnknownReference { - field: "remote coverage watermark shard", - }); - } - let cache_field_count = [ - self.cache_generation.is_some(), - self.cache_not_after.is_some(), - self.cache_age_micros.is_some(), - self.cache_grant_snapshot.is_some(), - ] - .into_iter() - .filter(|present| *present) - .count(); - if cache_field_count != 0 && cache_field_count != 4 { - return Err(DomainError::UnknownReference { - field: "remote coverage cache state", - }); - } - if let Some(cache_grant_snapshot) = &self.cache_grant_snapshot { - cache_grant_snapshot.validate()?; - } - Ok(()) - } - - fn has_fresh_cache_at( - &self, - evaluated_at: UtcMicros, - placement_version: &EntityVersionId, - ) -> bool { - self.cache_generation.is_some() - && self.cache_age_micros.is_some() - && self.cache_not_after.is_some_and(|cache_not_after| { - self.cache_grant_snapshot.as_ref().is_some_and(|snapshot| { - snapshot.proves_current_access( - evaluated_at, - cache_not_after, - placement_version, - &self.authority_id, - self.authority_epoch, - ) - }) - }) - } - - fn is_authoritatively_complete(&self) -> bool { - self.served_by_role == BrainNodeRoleV1::Authority - && self.captured_watermark.is_some() - && self.pending_local_observations == 0 - && self.pending_tombstone_acks == 0 - } -} - -/// A vector whose length cannot exceed `MAX`. -/// -/// Deserialization consumes at most `MAX` values into memory. If another value -/// is present, it is ignored and the sequence is rejected immediately. -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct BoundedVec(Vec); - -impl BoundedVec { - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn is_empty(&self) -> bool { - self.0.is_empty() - } - - pub fn iter(&self) -> std::slice::Iter<'_, T> { - self.0.iter() - } - - pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> { - self.0.iter_mut() - } -} - -impl TryFrom> for BoundedVec { - type Error = Vec; - - fn try_from(values: Vec) -> Result { - if values.len() <= MAX { - Ok(Self(values)) - } else { - Err(values) - } - } -} - -impl Index for BoundedVec { - type Output = T; - - fn index(&self, index: usize) -> &Self::Output { - &self.0[index] - } -} - -impl IndexMut for BoundedVec { - fn index_mut(&mut self, index: usize) -> &mut Self::Output { - &mut self.0[index] - } -} - -impl<'a, T, const MAX: usize> IntoIterator for &'a BoundedVec { - type Item = &'a T; - type IntoIter = std::slice::Iter<'a, T>; - - fn into_iter(self) -> Self::IntoIter { - self.0.iter() - } -} - -impl<'a, T, const MAX: usize> IntoIterator for &'a mut BoundedVec { - type Item = &'a mut T; - type IntoIter = std::slice::IterMut<'a, T>; - - fn into_iter(self) -> Self::IntoIter { - self.0.iter_mut() - } -} - -impl IntoIterator for BoundedVec { - type Item = T; - type IntoIter = std::vec::IntoIter; - - fn into_iter(self) -> Self::IntoIter { - self.0.into_iter() - } -} - -impl Serialize for BoundedVec -where - T: Serialize, -{ - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - self.0.serialize(serializer) - } -} - -struct BoundedVecVisitor(PhantomData); - -impl<'de, T, const MAX: usize> Visitor<'de> for BoundedVecVisitor -where - T: Deserialize<'de>, -{ - type Value = BoundedVec; - - fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(formatter, "a sequence with at most {MAX} elements") - } - - fn visit_seq(self, mut sequence: A) -> Result - where - A: SeqAccess<'de>, - { - let mut values = Vec::with_capacity(sequence.size_hint().unwrap_or(0).min(MAX)); - while values.len() < MAX { - match sequence.next_element()? { - Some(value) => values.push(value), - None => return Ok(BoundedVec(values)), - } - } - if sequence.next_element::()?.is_some() { - return Err(serde::de::Error::invalid_length( - MAX.saturating_add(1), - &self, - )); - } - Ok(BoundedVec(values)) - } -} - -impl<'de, T, const MAX: usize> Deserialize<'de> for BoundedVec -where - T: Deserialize<'de>, -{ - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - deserializer.deserialize_seq(BoundedVecVisitor(PhantomData)) - } -} - -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] -#[serde(deny_unknown_fields)] -pub struct RemoteCoverageV1 { - pub brain_id: BrainId, - pub placement_version: EntityVersionId, - /// Immutable instant at which this coverage decision was evaluated. - pub evaluated_at: UtcMicros, - pub requested_consistency: ReadConsistencyV1, - pub shards: BoundedVec, -} - -impl RemoteCoverageV1 { - fn validate(&self) -> Result<(), DomainError> { - self.brain_id.validate()?; - self.placement_version.validate()?; - ensure_unique( - self.shards.iter().map(|shard| &shard.shard_id), - "remote coverage shards", - )?; - for shard in &self.shards { - shard.validate()?; - } - Ok(()) - } - - fn is_complete_for_requested_consistency(&self) -> bool { - match self.requested_consistency { - ReadConsistencyV1::Authoritative => self - .shards - .iter() - .all(RemoteShardCoverageV1::is_authoritatively_complete), - ReadConsistencyV1::BoundedStale { max_lag_micros } => self.shards.iter().all(|shard| { - shard.pending_tombstone_acks == 0 - && shard - .sync_lag_micros - .is_some_and(|lag| lag <= max_lag_micros) - }), - ReadConsistencyV1::OfflineCache => self.shards.iter().all(|shard| { - shard.has_fresh_cache_at(self.evaluated_at, &self.placement_version) - && shard.pending_tombstone_acks == 0 - }), - } - } -} - -/// Exact per-shard disposition captured with a retrieval result. -/// -/// The in-memory authority is one map: a shard cannot occupy two disposition -/// groups. Custom serde preserves the grouped-vector V1 fixture wire form. -#[derive(Clone, Debug, Default, PartialEq, Eq)] -pub struct CoverageReportV1 { - pub dispositions: BTreeMap, - pub freshness: BTreeMap, - pub retention_watermark: Option, - pub universe: CoverageUniverseKnowledgeV1, - pub remote: Option, -} - -impl CoverageReportV1 { - pub fn validate(&self) -> Result<(), DomainError> { - for shard in self.dispositions.keys() { - shard.validate()?; - } - for (shard, watermark) in &self.freshness { - shard.validate()?; - if !self.dispositions.contains_key(shard) || shard != &watermark.shard_id { - return Err(DomainError::UnknownReference { - field: "coverage freshness shard", - }); - } - } - if let Some(retention) = &self.retention_watermark { - for class in retention.cutoffs.keys() { - validate_canonical_string(class.as_str(), "RetentionClass")?; - } - } - if let Some(remote) = &self.remote { - remote.validate()?; - if remote - .shards - .iter() - .any(|shard| !self.dispositions.contains_key(&shard.shard_id)) - { - return Err(DomainError::UnknownReference { - field: "remote coverage disposition shard", - }); - } - } - Ok(()) - } - - pub fn is_complete(&self) -> bool { - if self.universe == CoverageUniverseKnowledgeV1::Unknown - || self.dispositions.is_empty() - || self - .dispositions - .values() - .any(|disposition| *disposition != ShardDispositionV1::Searched) - { - return false; - } - self.remote - .as_ref() - .is_none_or(RemoteCoverageV1::is_complete_for_requested_consistency) - } - - pub fn disposition(&self, shard: &ShardId) -> Option { - self.dispositions.get(shard).copied() - } -} - -#[derive(Default, Deserialize)] -#[serde(deny_unknown_fields)] -struct CoverageWireV1 { - #[serde(default)] - searched: Vec, - #[serde(default)] - skipped: Vec, - #[serde(default)] - stale: Vec, - #[serde(default)] - unavailable: Vec, - #[serde(default)] - incompatible: Vec, - #[serde(default)] - locked: Vec, - #[serde(default)] - redacted: Vec, - #[serde(default)] - truncated: Vec, - #[serde(default)] - freshness: BTreeMap, - #[serde(default, skip_serializing_if = "Option::is_none")] - retention_watermark: Option, - #[serde(default)] - unknown_coverage: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - remote: Option, -} - -#[derive(Serialize)] -#[serde(deny_unknown_fields)] -struct CoverageWireRefV1<'a> { - #[serde(default)] - searched: Vec<&'a ShardId>, - #[serde(default)] - skipped: Vec<&'a ShardId>, - #[serde(default)] - stale: Vec<&'a ShardId>, - #[serde(default)] - unavailable: Vec<&'a ShardId>, - #[serde(default)] - incompatible: Vec<&'a ShardId>, - #[serde(default)] - locked: Vec<&'a ShardId>, - #[serde(default)] - redacted: Vec<&'a ShardId>, - #[serde(default)] - truncated: Vec<&'a ShardId>, - #[serde(default)] - freshness: &'a BTreeMap, - #[serde(default, skip_serializing_if = "Option::is_none")] - retention_watermark: Option<&'a EvidenceRetentionWatermark>, - #[serde(default)] - unknown_coverage: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - remote: Option<&'a RemoteCoverageV1>, -} - -impl CoverageWireV1 { - fn add_group( - dispositions: &mut BTreeMap, - shards: Vec, - disposition: ShardDispositionV1, - ) -> Result<(), DomainError> { - for shard in shards { - if dispositions.insert(shard, disposition).is_some() { - return Err(DomainError::DuplicateId { - field: "coverage dispositions", - }); - } - } - Ok(()) - } -} - -impl Serialize for CoverageReportV1 { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - let mut searched = Vec::new(); - let mut skipped = Vec::new(); - let mut stale = Vec::new(); - let mut unavailable = Vec::new(); - let mut incompatible = Vec::new(); - let mut locked = Vec::new(); - let mut redacted = Vec::new(); - let mut truncated = Vec::new(); - for (shard, disposition) in &self.dispositions { - let group = match disposition { - ShardDispositionV1::Searched => &mut searched, - ShardDispositionV1::Skipped => &mut skipped, - ShardDispositionV1::Stale => &mut stale, - ShardDispositionV1::Unavailable => &mut unavailable, - ShardDispositionV1::Incompatible => &mut incompatible, - ShardDispositionV1::Locked => &mut locked, - ShardDispositionV1::Redacted => &mut redacted, - ShardDispositionV1::Truncated => &mut truncated, - }; - group.push(shard); - } - CoverageWireRefV1 { - searched, - skipped, - stale, - unavailable, - incompatible, - locked, - redacted, - truncated, - freshness: &self.freshness, - retention_watermark: self.retention_watermark.as_ref(), - unknown_coverage: Some(self.universe == CoverageUniverseKnowledgeV1::Unknown), - remote: self.remote.as_ref(), - } - .serialize(serializer) - } -} - -impl<'de> Deserialize<'de> for CoverageReportV1 { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let wire = CoverageWireV1::deserialize(deserializer)?; - let mut dispositions = BTreeMap::new(); - CoverageWireV1::add_group( - &mut dispositions, - wire.searched, - ShardDispositionV1::Searched, - ) - .and_then(|_| { - CoverageWireV1::add_group(&mut dispositions, wire.skipped, ShardDispositionV1::Skipped) - }) - .and_then(|_| { - CoverageWireV1::add_group(&mut dispositions, wire.stale, ShardDispositionV1::Stale) - }) - .and_then(|_| { - CoverageWireV1::add_group( - &mut dispositions, - wire.unavailable, - ShardDispositionV1::Unavailable, - ) - }) - .and_then(|_| { - CoverageWireV1::add_group( - &mut dispositions, - wire.incompatible, - ShardDispositionV1::Incompatible, - ) - }) - .and_then(|_| { - CoverageWireV1::add_group(&mut dispositions, wire.locked, ShardDispositionV1::Locked) - }) - .and_then(|_| { - CoverageWireV1::add_group( - &mut dispositions, - wire.redacted, - ShardDispositionV1::Redacted, - ) - }) - .and_then(|_| { - CoverageWireV1::add_group( - &mut dispositions, - wire.truncated, - ShardDispositionV1::Truncated, - ) - }) - .map_err(serde::de::Error::custom)?; - - let report = Self { - dispositions, - freshness: wire.freshness, - retention_watermark: wire.retention_watermark, - universe: match wire.unknown_coverage { - Some(false) => CoverageUniverseKnowledgeV1::Known, - Some(true) | None => CoverageUniverseKnowledgeV1::Unknown, - }, - remote: wire.remote, - }; - report.validate().map_err(serde::de::Error::custom)?; - Ok(report) - } -} diff --git a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/error.rs b/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/error.rs deleted file mode 100644 index 83725c9367..0000000000 --- a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/error.rs +++ /dev/null @@ -1,38 +0,0 @@ -use thiserror::Error; - -/// Validation failures for pure research-domain values. -#[derive(Clone, Debug, Error, PartialEq, Eq)] -pub enum DomainError { - #[error("{field} must not be empty")] - Empty { field: &'static str }, - #[error("{field} is not canonical")] - NonCanonical { field: &'static str }, - #[error("{field} contains a duplicate identity")] - DuplicateId { field: &'static str }, - #[error("{field} references an unknown identity")] - UnknownReference { field: &'static str }, - #[error("{field} is not pinned to the required snapshot")] - SnapshotMismatch { field: &'static str }, - #[error("confidence must be finite and within [0.0, 1.0]")] - InvalidConfidence, - #[error("{field} violates the structural bounds for sanitized text")] - UnsafeText { field: &'static str }, - #[error("an Activity primary subject cannot also have related_activity")] - ActivityFacetOnActivitySubject, - #[error("a manifest cannot supersede itself")] - SelfSupersession, - #[error("direct authorship requires provider-linked activity evidence")] - AuthorshipWithoutProviderLinkage, - #[error("time interval start must not be after its end")] - InvalidTimeInterval, - #[error("redacted and rejected counts cannot exceed scanned count")] - InvalidRedactionCounts, - #[error( - "evidence declared by a user or provider, or directly observed, requires confidence 1.0" - )] - NonCertainDeclaration, - #[error("manifest digest does not match its canonical domain-separated payload")] - DigestMismatch, - #[error("canonical serialization failed: {0}")] - CanonicalSerialization(String), -} diff --git a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/time.rs b/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/time.rs deleted file mode 100644 index 07e04fd372..0000000000 --- a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/time.rs +++ /dev/null @@ -1,25 +0,0 @@ -use serde::{Deserialize, Serialize}; - -use super::error::DomainError; - -/// UTC timestamp represented as microseconds from the Unix epoch. -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(transparent)] -pub struct UtcMicros(pub i64); - -/// Closed half-open occurrence interval. -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(deny_unknown_fields)] -pub struct TimeInterval { - pub start: UtcMicros, - pub end: UtcMicros, -} - -impl TimeInterval { - pub fn validate(&self) -> Result<(), DomainError> { - if self.start > self.end { - return Err(DomainError::InvalidTimeInterval); - } - Ok(()) - } -} diff --git a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/watermark.rs b/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/watermark.rs deleted file mode 100644 index 2bcb1b50a7..0000000000 --- a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/watermark.rs +++ /dev/null @@ -1,50 +0,0 @@ -use std::collections::BTreeMap; - -use serde::{Deserialize, Serialize}; - -use super::id::ShardId; - -/// Per-shard progress without a fabricated global sequence. -#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq)] -#[serde(deny_unknown_fields)] -pub struct VectorWatermark { - pub components: BTreeMap, -} - -impl VectorWatermark { - pub fn dominates(&self, other: &Self) -> bool { - other - .components - .iter() - .all(|(shard, sequence)| self.components.get(shard).copied().unwrap_or(0) >= *sequence) - } - - pub fn partial_cmp_components(&self, other: &Self) -> Option { - let self_dominates = self.dominates(other); - let other_dominates = other.dominates(self); - match (self_dominates, other_dominates) { - (true, true) => Some(std::cmp::Ordering::Equal), - (true, false) => Some(std::cmp::Ordering::Greater), - (false, true) => Some(std::cmp::Ordering::Less), - (false, false) => None, - } - } - - pub fn merge_max(&self, other: &Self) -> Self { - let mut components = self.components.clone(); - for (shard, sequence) in &other.components { - components - .entry(shard.clone()) - .and_modify(|current| *current = (*current).max(*sequence)) - .or_insert(*sequence); - } - Self { components } - } -} - -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(deny_unknown_fields)] -pub struct ShardWatermark { - pub shard_id: ShardId, - pub outbox_sequence: u64, -} diff --git a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/session.rs b/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/session.rs deleted file mode 100644 index 4c92397cae..0000000000 --- a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/session.rs +++ /dev/null @@ -1,2114 +0,0 @@ -//! Pure session and temporal-retrieval contracts. -//! -//! These values carry identity, temporal, authority, coverage, and compact -//! context metadata only. Persistence, policy, hydration, and query execution -//! remain outside the domain crate. - -use std::collections::BTreeSet; -use std::fmt::{self, Write}; - -use serde::{Deserialize, Deserializer, Serialize}; -use sha2::{Digest, Sha256}; -use thiserror::Error; - -use crate::observation::{CanonicalMessageRoleV1, CanonicalObservationIdV1}; -use crate::research::{ - AgentInstanceId, ComponentVersion, DataVersionDigest, EvidenceClass, MessageId, ObservationId, - RetrievalAnchorId, SanitizationReceiptRefV1, SessionId, ThreadId, TurnId, UtcMicros, -}; - -const MESSAGE_OCCURRENCE_ID_DOMAIN: &[u8] = b"tracedecay.session.message-occurrence.v1\0"; - -/// Validation failures at the session-domain boundary. -#[derive(Clone, Debug, Error, PartialEq, Eq)] -pub enum SessionContractError { - #[error("{field} is not a canonical identity")] - InvalidIdentity { field: &'static str }, - #[error("{field} must be non-zero")] - ZeroValue { field: &'static str }, - #[error("a byte range must be non-empty and ordered")] - InvalidByteRange, - #[error("message occurrence identity does not match its observation and ordinal")] - OccurrenceIdentityMismatch, - #[error("a logical copy cannot reference itself")] - CopySelfReference, - #[error("copy proof does not identify the copied-from occurrence")] - CopyProofSourceMismatch, - #[error("a temporal assertion cannot relate an anchor to itself")] - AssertionSelfReference, - #[error("a session summary requires at least one exact source anchor")] - SummarySourcesRequired, - #[error("a session summary source anchor is duplicated")] - DuplicateSummarySource, - #[error("a session summary cannot predate its knowledge horizon")] - InvalidSummaryHorizon, - #[error("a session summary cannot name itself as predecessor")] - SummarySelfPredecessor, - #[error("{group} grouping provenance requires a corresponding identity")] - GroupingProvenanceWithoutId { group: &'static str }, - #[error("{group} identity requires grouping provenance")] - GroupingIdWithoutProvenance { group: &'static str }, - #[error("compact context contains a duplicate anchor")] - DuplicateContextAnchor, - #[error("compact context encoded bytes do not match its records")] - CompactContextEncodedBytesMismatch, - #[error("compact context record bytes overflow the aggregate")] - CompactContextEncodedBytesOverflow, - #[error("a temporal coverage interval requires at least one bound")] - EmptyCoverageInterval, - #[error("a temporal coverage interval has reversed bounds")] - ReversedCoverageInterval, - #[error("source coverage intervals are not canonical")] - NonCanonicalCoverageIntervals, - #[error("source coverage frontiers are inconsistent")] - InvalidSourceCoverageFrontiers, - #[error("source coverage state and reason disagree")] - InvalidSourceCoverageState, - #[error("a source coverage receipt requires at least one source")] - SourceCoverageRequired, - #[error("a source coverage receipt contains duplicate sources")] - DuplicateSourceCoverage, - #[error("source coverage does not match the receipt request")] - SourceCoverageRequestMismatch, - #[error("a refresh key requires at least one source target")] - RefreshSourcesRequired, - #[error("a refresh key contains duplicate source targets")] - DuplicateRefreshSource, - #[error("a refresh source target regresses its observed frontier")] - InvalidRefreshSourceFrontier, - #[error("derived evidence requires at least one ordered member")] - DerivedEvidenceMembersRequired, - #[error("derived evidence contains a duplicate occurrence member")] - DuplicateDerivedEvidenceMember, - #[error("derived evidence membership ordinals are not contiguous")] - NoncontiguousDerivedEvidenceOrdinals, - #[error("derived evidence endpoints do not match the ordered manifest")] - DerivedEvidenceEndpointMismatch, - #[error("derived evidence session identity mismatches its members")] - DerivedEvidenceSessionMismatch, - #[error("derived evidence authority must be derived_projection")] - DerivedEvidenceAuthorityMismatch, - #[error("derived evidence member digest does not match membership")] - DerivedEvidenceMemberDigestMismatch, -} - -macro_rules! session_string_id { - ($($name:ident),+ $(,)?) => {$( - #[derive(Clone, Debug, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash)] - #[serde(transparent)] - pub struct $name(String); - - impl $name { - pub fn new(value: impl Into) -> Result { - let value = value.into(); - if value.is_empty() - || value.trim() != value - || value.len() > 512 - || value.chars().any(char::is_control) - { - return Err(SessionContractError::InvalidIdentity { - field: stringify!($name), - }); - } - Ok(Self(value)) - } - - pub fn as_str(&self) -> &str { - &self.0 - } - } - - impl<'de> Deserialize<'de> for $name { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - Self::new(String::deserialize(deserializer)?) - .map_err(serde::de::Error::custom) - } - } - - impl fmt::Display for $name { - fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - formatter.write_str(&self.0) - } - } - )+}; -} - -session_string_id!( - SessionSummaryIdV1, - TemporalAssertionIdV1, - SessionRefreshOperationIdV1, - SessionCursorKeyIdV1, - SessionSourceIdV1, -); - -/// Stable identity of one projected output from a canonical observation. -#[derive(Clone, Debug, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(transparent)] -pub struct MessageOccurrenceIdV1(String); - -impl MessageOccurrenceIdV1 { - pub fn derive( - observation_id: &CanonicalObservationIdV1, - output_ordinal: ProjectionOutputOrdinalV1, - ) -> Self { - let mut hasher = Sha256::new(); - hasher.update(MESSAGE_OCCURRENCE_ID_DOMAIN); - hasher.update(observation_id.as_str().as_bytes()); - hasher.update(output_ordinal.value().to_be_bytes()); - let digest = hasher.finalize(); - let mut encoded = String::with_capacity(71); - encoded.push_str("sha256:"); - for byte in digest { - write!(&mut encoded, "{byte:02x}").expect("writing to a String cannot fail"); - } - Self(encoded) - } - - pub fn new(value: impl Into) -> Result { - let value = value.into(); - let valid = value.strip_prefix("sha256:").is_some_and(|encoded| { - encoded.len() == 64 - && encoded - .bytes() - .all(|byte| byte.is_ascii_digit() || (b'a'..=b'f').contains(&byte)) - }); - if !valid { - return Err(SessionContractError::InvalidIdentity { - field: "MessageOccurrenceIdV1", - }); - } - Ok(Self(value)) - } - - pub fn as_str(&self) -> &str { - &self.0 - } -} - -impl<'de> Deserialize<'de> for MessageOccurrenceIdV1 { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - Self::new(String::deserialize(deserializer)?).map_err(serde::de::Error::custom) - } -} - -impl fmt::Display for MessageOccurrenceIdV1 { - fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - formatter.write_str(&self.0) - } -} - -/// Zero-based output position within one canonical observation projection. -#[derive( - Clone, Copy, Debug, Default, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash, -)] -#[serde(transparent)] -pub struct ProjectionOutputOrdinalV1(u32); - -impl ProjectionOutputOrdinalV1 { - pub const fn new(value: u32) -> Self { - Self(value) - } - - pub const fn value(self) -> u32 { - self.0 - } -} - -macro_rules! nonzero_numeric_value { - ($name:ident, $integer:ty, $field:literal) => { - #[derive(Clone, Copy, Debug, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash)] - #[serde(transparent)] - pub struct $name($integer); - - impl $name { - pub fn new(value: $integer) -> Result { - if value == 0 { - return Err(SessionContractError::ZeroValue { field: $field }); - } - Ok(Self(value)) - } - - pub const fn value(self) -> $integer { - self.0 - } - } - - impl<'de> Deserialize<'de> for $name { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - Self::new(<$integer>::deserialize(deserializer)?).map_err(serde::de::Error::custom) - } - } - }; -} - -nonzero_numeric_value!( - SessionProjectionGenerationV1, - u64, - "session projection generation" -); -nonzero_numeric_value!(SessionCursorVersionV1, u16, "session cursor version"); - -/// Persisted signing-key reference used by authenticated collection cursors. -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(deny_unknown_fields)] -pub struct SignedCursorKeyRefV1 { - pub key_id: SessionCursorKeyIdV1, - pub version: SessionCursorVersionV1, -} - -/// Requested temporal interpretation. -#[derive(Clone, Copy, Debug, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)] -pub enum TemporalModeV1 { - Current, - AsOf { cutoff: UtcMicros }, - Evolution, - Forensic, -} - -impl TemporalModeV1 { - pub const fn as_str(self) -> &'static str { - match self { - Self::Current => "current", - Self::AsOf { .. } => "as_of", - Self::Evolution => "evolution", - Self::Forensic => "forensic", - } - } -} - -impl<'de> Deserialize<'de> for TemporalModeV1 { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - #[derive(Deserialize)] - #[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)] - enum Wire { - Current {}, - AsOf { cutoff: UtcMicros }, - Evolution {}, - Forensic {}, - } - - Ok(match Wire::deserialize(deserializer)? { - Wire::Current {} => Self::Current, - Wire::AsOf { cutoff } => Self::AsOf { cutoff }, - Wire::Evolution {} => Self::Evolution, - Wire::Forensic {} => Self::Forensic, - }) - } -} - -/// Retrieval unit selected by the caller. -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(rename_all = "snake_case")] -pub enum RetrievalGrainV1 { - Occurrence, - LogicalMessage, - Turn, - Session, - Thread, - Agent, - Summary, - EvidenceSpan, - EvidenceBurst, -} - -impl RetrievalGrainV1 { - pub const fn as_str(self) -> &'static str { - match self { - Self::Occurrence => "occurrence", - Self::LogicalMessage => "logical_message", - Self::Turn => "turn", - Self::Session => "session", - Self::Thread => "thread", - Self::Agent => "agent", - Self::Summary => "summary", - Self::EvidenceSpan => "evidence_span", - Self::EvidenceBurst => "evidence_burst", - } - } -} - -/// Canonical half-open UTF-8 byte range retained by exact retrieval evidence. -#[derive(Clone, Copy, Debug, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct ByteRangeV1 { - start: u64, - end: u64, -} - -impl ByteRangeV1 { - pub const fn new(start: u64, end: u64) -> Result { - if start >= end { - return Err(SessionContractError::InvalidByteRange); - } - Ok(Self { start, end }) - } - - pub const fn start(self) -> u64 { - self.start - } - - pub const fn end(self) -> u64 { - self.end - } -} - -impl<'de> Deserialize<'de> for ByteRangeV1 { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - #[derive(Deserialize)] - #[serde(deny_unknown_fields)] - struct SerializedByteRange { - start: u64, - end: u64, - } - - let range = SerializedByteRange::deserialize(deserializer)?; - Self::new(range.start, range.end).map_err(serde::de::Error::custom) - } -} - -/// Valid-time evidence for an occurrence or assertion. -#[derive(Clone, Copy, Debug, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)] -pub enum TemporalValidityV1 { - Known { valid_at: UtcMicros }, - Unknown, -} - -impl TemporalValidityV1 { - /// Whether evidence may participate in a representative answer for `mode`. - /// - /// `as_of` is intentionally strict: both knowledge and valid time must be - /// at or before the cutoff, and unknown valid time is excluded. - pub const fn is_representative_at(self, knowledge_at: UtcMicros, mode: TemporalModeV1) -> bool { - match mode { - TemporalModeV1::AsOf { cutoff } => match self { - Self::Known { valid_at } => knowledge_at.0 <= cutoff.0 && valid_at.0 <= cutoff.0, - Self::Unknown => false, - }, - TemporalModeV1::Current | TemporalModeV1::Evolution | TemporalModeV1::Forensic => true, - } - } -} - -impl<'de> Deserialize<'de> for TemporalValidityV1 { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - #[derive(Deserialize)] - #[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)] - enum Wire { - Known { valid_at: UtcMicros }, - Unknown {}, - } - - Ok(match Wire::deserialize(deserializer)? { - Wire::Known { valid_at } => Self::Known { valid_at }, - Wire::Unknown {} => Self::Unknown, - }) - } -} - -/// Whether a Turn/thread identity was observed or deterministically projected. -#[derive(Clone, Debug, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)] -pub enum GroupingProvenanceV1 { - ProviderNative, - DerivedRoleBoundary { projector_version: ComponentVersion }, -} - -impl GroupingProvenanceV1 { - pub fn validate(&self) -> Result<(), SessionContractError> { - match self { - Self::ProviderNative => Ok(()), - Self::DerivedRoleBoundary { projector_version } => projector_version - .validate() - .map_err(|_| SessionContractError::InvalidIdentity { - field: "grouping projector version", - }), - } - } -} - -impl<'de> Deserialize<'de> for GroupingProvenanceV1 { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - #[derive(Deserialize)] - #[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)] - enum Wire { - ProviderNative {}, - DerivedRoleBoundary { projector_version: ComponentVersion }, - } - - Ok(match Wire::deserialize(deserializer)? { - Wire::ProviderNative {} => Self::ProviderNative, - Wire::DerivedRoleBoundary { projector_version } => { - Self::DerivedRoleBoundary { projector_version } - } - }) - } -} - -/// Authority class attached to session evidence. -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(rename_all = "snake_case")] -pub enum SessionAuthorityClassV1 { - ProviderNative, - CanonicalObservation, - ExplicitAnchorAssertion, - DerivedProjection, - ImmutableSummary, -} - -impl SessionAuthorityClassV1 { - pub const fn as_str(self) -> &'static str { - match self { - Self::ProviderNative => "provider_native", - Self::CanonicalObservation => "canonical_observation", - Self::ExplicitAnchorAssertion => "explicit_anchor_assertion", - Self::DerivedProjection => "derived_projection", - Self::ImmutableSummary => "immutable_summary", - } - } -} - -/// Exact evidence and sanitization references behind one session-domain row. -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] -#[serde(deny_unknown_fields)] -pub struct SessionEvidenceMetadataV1 { - pub authority: SessionAuthorityClassV1, - pub evidence_class: EvidenceClass, - pub source_anchor_id: RetrievalAnchorId, - pub sanitization_receipt: SanitizationReceiptRefV1, -} - -impl SessionEvidenceMetadataV1 { - pub fn validate(&self) -> Result<(), SessionContractError> { - self.source_anchor_id - .validate() - .map_err(|_| SessionContractError::InvalidIdentity { - field: "session evidence source anchor", - })?; - self.sanitization_receipt - .validate() - .map_err(|_| SessionContractError::InvalidIdentity { - field: "session evidence sanitization receipt", - }) - } -} - -/// Immutable projected occurrence of one message-like observation output. -#[derive(Clone, Debug, Serialize, PartialEq, Eq)] -#[serde(deny_unknown_fields)] -pub struct MessageOccurrenceRecordV1 { - pub occurrence_id: MessageOccurrenceIdV1, - pub source_observation_id: CanonicalObservationIdV1, - pub projection_output_ordinal: ProjectionOutputOrdinalV1, - pub retrieval_anchor_id: RetrievalAnchorId, - pub session_id: SessionId, - pub thread_id: Option, - pub thread_grouping: Option, - pub turn_id: Option, - pub turn_grouping: Option, - pub message_id: Option, - pub agent_id: Option, - pub role: CanonicalMessageRoleV1, - pub knowledge_at: UtcMicros, - pub valid_time: TemporalValidityV1, - pub evidence: SessionEvidenceMetadataV1, -} - -impl MessageOccurrenceRecordV1 { - pub fn validate(&self) -> Result<(), SessionContractError> { - if self.occurrence_id - != MessageOccurrenceIdV1::derive( - &self.source_observation_id, - self.projection_output_ordinal, - ) - { - return Err(SessionContractError::OccurrenceIdentityMismatch); - } - self.retrieval_anchor_id - .validate() - .map_err(|_| SessionContractError::InvalidIdentity { - field: "occurrence retrieval anchor", - })?; - self.session_id - .validate() - .map_err(|_| SessionContractError::InvalidIdentity { - field: "occurrence session", - })?; - for (field, value) in [ - ( - "occurrence thread", - self.thread_id.as_ref().map(ThreadId::validate), - ), - ( - "occurrence turn", - self.turn_id.as_ref().map(TurnId::validate), - ), - ( - "occurrence message", - self.message_id.as_ref().map(MessageId::validate), - ), - ( - "occurrence agent", - self.agent_id.as_ref().map(AgentInstanceId::validate), - ), - ] { - if value.is_some_and(|result| result.is_err()) { - return Err(SessionContractError::InvalidIdentity { field }); - } - } - for (group, id_present, provenance) in [ - ( - "thread", - self.thread_id.is_some(), - self.thread_grouping.as_ref(), - ), - ("turn", self.turn_id.is_some(), self.turn_grouping.as_ref()), - ] { - match (id_present, provenance) { - (false, Some(_)) => { - return Err(SessionContractError::GroupingProvenanceWithoutId { group }); - } - (true, None) => { - return Err(SessionContractError::GroupingIdWithoutProvenance { group }); - } - (true, Some(provenance)) => provenance.validate()?, - (false, None) => {} - } - } - self.evidence.validate() - } -} - -impl<'de> Deserialize<'de> for MessageOccurrenceRecordV1 { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - #[derive(Deserialize)] - #[serde(deny_unknown_fields)] - struct Wire { - occurrence_id: MessageOccurrenceIdV1, - source_observation_id: CanonicalObservationIdV1, - projection_output_ordinal: ProjectionOutputOrdinalV1, - retrieval_anchor_id: RetrievalAnchorId, - session_id: SessionId, - thread_id: Option, - thread_grouping: Option, - turn_id: Option, - turn_grouping: Option, - message_id: Option, - agent_id: Option, - role: CanonicalMessageRoleV1, - knowledge_at: UtcMicros, - valid_time: TemporalValidityV1, - evidence: SessionEvidenceMetadataV1, - } - - let wire = Wire::deserialize(deserializer)?; - let record = Self { - occurrence_id: wire.occurrence_id, - source_observation_id: wire.source_observation_id, - projection_output_ordinal: wire.projection_output_ordinal, - retrieval_anchor_id: wire.retrieval_anchor_id, - session_id: wire.session_id, - thread_id: wire.thread_id, - thread_grouping: wire.thread_grouping, - turn_id: wire.turn_id, - turn_grouping: wire.turn_grouping, - message_id: wire.message_id, - agent_id: wire.agent_id, - role: wire.role, - knowledge_at: wire.knowledge_at, - valid_time: wire.valid_time, - evidence: wire.evidence, - }; - record.validate().map_err(serde::de::Error::custom)?; - Ok(record) - } -} - -/// Evidence that can prove two occurrences are logical copies. -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)] -pub enum CopyProofV1 { - ProviderLinkage { - source_occurrence_id: MessageOccurrenceIdV1, - provider_record_id: ObservationId, - }, - ParentMessageLinkage { - source_occurrence_id: MessageOccurrenceIdV1, - parent_message_id: MessageId, - }, - ExplicitAnchorAssertion { - source_occurrence_id: MessageOccurrenceIdV1, - assertion_anchor_id: RetrievalAnchorId, - }, -} - -impl CopyProofV1 { - pub fn source_occurrence_id(&self) -> &MessageOccurrenceIdV1 { - match self { - Self::ProviderLinkage { - source_occurrence_id, - .. - } - | Self::ParentMessageLinkage { - source_occurrence_id, - .. - } - | Self::ExplicitAnchorAssertion { - source_occurrence_id, - .. - } => source_occurrence_id, - } - } -} - -/// Immutable evidence-backed logical-copy edge. -#[derive(Clone, Debug, Serialize, PartialEq, Eq)] -#[serde(deny_unknown_fields)] -pub struct LogicalCopyRecordV1 { - pub occurrence_id: MessageOccurrenceIdV1, - pub copied_from_occurrence_id: MessageOccurrenceIdV1, - pub proof: CopyProofV1, - /// When the copy edge became visible to the authoritative store/projection. - pub knowledge_at: UtcMicros, - /// Independent represented-world validity; legacy rows default to unknown. - pub valid_time: TemporalValidityV1, -} - -impl LogicalCopyRecordV1 { - pub fn validate(&self) -> Result<(), SessionContractError> { - if self.occurrence_id == self.copied_from_occurrence_id { - return Err(SessionContractError::CopySelfReference); - } - if self.proof.source_occurrence_id() != &self.copied_from_occurrence_id { - return Err(SessionContractError::CopyProofSourceMismatch); - } - Ok(()) - } -} - -impl<'de> Deserialize<'de> for LogicalCopyRecordV1 { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - #[derive(Deserialize)] - #[serde(deny_unknown_fields)] - struct Wire { - occurrence_id: MessageOccurrenceIdV1, - copied_from_occurrence_id: MessageOccurrenceIdV1, - proof: CopyProofV1, - #[serde(default)] - knowledge_at: Option, - #[serde(default)] - valid_time: Option, - } - - let wire = Wire::deserialize(deserializer)?; - let record = Self { - occurrence_id: wire.occurrence_id, - copied_from_occurrence_id: wire.copied_from_occurrence_id, - proof: wire.proof, - // Legacy copy wires omit bitemporal fields; preserve unknown validity - // and a zero knowledge watermark rather than inventing provider time. - knowledge_at: wire.knowledge_at.unwrap_or(UtcMicros(0)), - valid_time: wire.valid_time.unwrap_or(TemporalValidityV1::Unknown), - }; - record.validate().map_err(serde::de::Error::custom)?; - Ok(record) - } -} - -/// Temporal relationship asserted between two exact anchors. -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(rename_all = "snake_case")] -pub enum TemporalAssertionKindV1 { - Corrects, - Supersedes, - Contradicts, - Supports, -} - -impl TemporalAssertionKindV1 { - pub const fn as_str(self) -> &'static str { - match self { - Self::Corrects => "corrects", - Self::Supersedes => "supersedes", - Self::Contradicts => "contradicts", - Self::Supports => "supports", - } - } -} - -/// Immutable temporal assertion over exact evidence anchors. -#[derive(Clone, Debug, Serialize, PartialEq, Eq)] -#[serde(deny_unknown_fields)] -pub struct TemporalAssertionRecordV1 { - pub assertion_id: TemporalAssertionIdV1, - pub kind: TemporalAssertionKindV1, - pub subject_anchor_id: RetrievalAnchorId, - pub object_anchor_id: RetrievalAnchorId, - pub knowledge_at: UtcMicros, - pub valid_time: TemporalValidityV1, - pub evidence: SessionEvidenceMetadataV1, -} - -impl TemporalAssertionRecordV1 { - pub fn validate(&self) -> Result<(), SessionContractError> { - if self.subject_anchor_id == self.object_anchor_id { - return Err(SessionContractError::AssertionSelfReference); - } - self.subject_anchor_id - .validate() - .and_then(|_| self.object_anchor_id.validate()) - .map_err(|_| SessionContractError::InvalidIdentity { - field: "temporal assertion anchor", - })?; - self.evidence.validate() - } -} - -impl<'de> Deserialize<'de> for TemporalAssertionRecordV1 { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - #[derive(Deserialize)] - #[serde(deny_unknown_fields)] - struct Wire { - assertion_id: TemporalAssertionIdV1, - kind: TemporalAssertionKindV1, - subject_anchor_id: RetrievalAnchorId, - object_anchor_id: RetrievalAnchorId, - knowledge_at: UtcMicros, - valid_time: TemporalValidityV1, - evidence: SessionEvidenceMetadataV1, - } - - let wire = Wire::deserialize(deserializer)?; - let record = Self { - assertion_id: wire.assertion_id, - kind: wire.kind, - subject_anchor_id: wire.subject_anchor_id, - object_anchor_id: wire.object_anchor_id, - knowledge_at: wire.knowledge_at, - valid_time: wire.valid_time, - evidence: wire.evidence, - }; - record.validate().map_err(serde::de::Error::custom)?; - Ok(record) - } -} - -/// Exact source-time horizon covered by an immutable summary. -#[derive(Clone, Copy, Debug, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(deny_unknown_fields)] -pub struct SummarySourceHorizonV1 { - pub knowledge_through: UtcMicros, - pub valid_through: Option, -} - -impl SummarySourceHorizonV1 { - pub fn validate(self) -> Result<(), SessionContractError> { - Ok(()) - } -} - -impl<'de> Deserialize<'de> for SummarySourceHorizonV1 { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - #[derive(Deserialize)] - #[serde(deny_unknown_fields)] - struct Wire { - knowledge_through: UtcMicros, - #[serde(deserialize_with = "deserialize_required_option")] - valid_through: Option, - } - - fn deserialize_required_option<'de, D, T>(deserializer: D) -> Result, D::Error> - where - D: Deserializer<'de>, - T: Deserialize<'de>, - { - Option::deserialize(deserializer) - } - - let wire = Wire::deserialize(deserializer)?; - let horizon = Self { - knowledge_through: wire.knowledge_through, - valid_through: wire.valid_through, - }; - horizon.validate().map_err(serde::de::Error::custom)?; - Ok(horizon) - } -} - -/// Publication metadata that binds a summary to its route and sanitization. -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] -#[serde(deny_unknown_fields)] -pub struct SummaryPublicationMetadataV1 { - pub model_route: ComponentVersion, - pub configuration_digest: DataVersionDigest, - pub sanitization_receipt: SanitizationReceiptRefV1, -} - -impl SummaryPublicationMetadataV1 { - pub fn validate(&self) -> Result<(), SessionContractError> { - self.model_route - .validate() - .and_then(|_| self.configuration_digest.validate()) - .and_then(|_| self.sanitization_receipt.validate()) - .map_err(|_| SessionContractError::InvalidIdentity { - field: "summary publication metadata", - }) - } -} - -/// Immutable summary node with exact, identity-unique source anchors. -#[derive(Clone, Debug, Serialize, PartialEq, Eq)] -#[serde(deny_unknown_fields)] -pub struct SessionSummaryRecordV1 { - summary_id: SessionSummaryIdV1, - session_id: SessionId, - summary_anchor_id: RetrievalAnchorId, - source_anchors: Vec, - source_horizon: SummarySourceHorizonV1, - created_at: UtcMicros, - predecessor_summary_id: Option, - publication: Option, -} - -impl SessionSummaryRecordV1 { - pub fn new( - summary_id: SessionSummaryIdV1, - session_id: SessionId, - summary_anchor_id: RetrievalAnchorId, - source_anchors: Vec, - source_horizon: SummarySourceHorizonV1, - created_at: UtcMicros, - ) -> Result { - if source_anchors.is_empty() { - return Err(SessionContractError::SummarySourcesRequired); - } - let mut unique = BTreeSet::new(); - if source_anchors - .iter() - .any(|source| !unique.insert(source.clone())) - { - return Err(SessionContractError::DuplicateSummarySource); - } - if created_at < source_horizon.knowledge_through { - return Err(SessionContractError::InvalidSummaryHorizon); - } - source_horizon.validate()?; - session_id - .validate() - .and_then(|_| summary_anchor_id.validate()) - .map_err(|_| SessionContractError::InvalidIdentity { - field: "session summary", - })?; - for source in &source_anchors { - source - .validate() - .map_err(|_| SessionContractError::InvalidIdentity { - field: "session summary source anchor", - })?; - } - let source_anchors = unique.into_iter().collect(); - Ok(Self { - summary_id, - session_id, - summary_anchor_id, - source_anchors, - source_horizon, - created_at, - predecessor_summary_id: None, - publication: None, - }) - } - - pub fn with_predecessor( - mut self, - predecessor: SessionSummaryIdV1, - ) -> Result { - if self.summary_id == predecessor { - return Err(SessionContractError::SummarySelfPredecessor); - } - self.predecessor_summary_id = Some(predecessor); - Ok(self) - } - - pub fn with_publication( - mut self, - publication: SummaryPublicationMetadataV1, - ) -> Result { - publication.validate()?; - self.publication = Some(publication); - Ok(self) - } - - pub fn summary_id(&self) -> &SessionSummaryIdV1 { - &self.summary_id - } - - pub fn session_id(&self) -> &SessionId { - &self.session_id - } - - pub fn summary_anchor_id(&self) -> &RetrievalAnchorId { - &self.summary_anchor_id - } - - pub fn source_anchors(&self) -> &[RetrievalAnchorId] { - &self.source_anchors - } - - pub fn source_horizon(&self) -> SummarySourceHorizonV1 { - self.source_horizon - } - - pub fn created_at(&self) -> UtcMicros { - self.created_at - } - - pub fn predecessor_summary_id(&self) -> Option<&SessionSummaryIdV1> { - self.predecessor_summary_id.as_ref() - } - - pub fn publication(&self) -> Option<&SummaryPublicationMetadataV1> { - self.publication.as_ref() - } -} - -impl<'de> Deserialize<'de> for SessionSummaryRecordV1 { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - #[derive(Deserialize)] - #[serde(deny_unknown_fields)] - struct Wire { - summary_id: SessionSummaryIdV1, - session_id: SessionId, - summary_anchor_id: RetrievalAnchorId, - source_anchors: Vec, - source_horizon: SummarySourceHorizonV1, - created_at: UtcMicros, - predecessor_summary_id: Option, - publication: Option, - } - - let wire = Wire::deserialize(deserializer)?; - let mut summary = Self::new( - wire.summary_id, - wire.session_id, - wire.summary_anchor_id, - wire.source_anchors, - wire.source_horizon, - wire.created_at, - ) - .map_err(serde::de::Error::custom)?; - if let Some(predecessor) = wire.predecessor_summary_id { - summary = summary - .with_predecessor(predecessor) - .map_err(serde::de::Error::custom)?; - } - if let Some(publication) = wire.publication { - summary = summary - .with_publication(publication) - .map_err(serde::de::Error::custom)?; - } - Ok(summary) - } -} - -/// Current hydration eligibility after authorization and retention rechecks. -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(rename_all = "snake_case")] -pub enum HydrationStateV1 { - Available, - RetainedButUnavailable, - Redacted, - Deleted, - RetentionExpired, - Unauthorized, - Locked, - UnverifiableLegacy, -} - -impl HydrationStateV1 { - pub const fn as_str(self) -> &'static str { - match self { - Self::Available => "available", - Self::RetainedButUnavailable => "retained_but_unavailable", - Self::Redacted => "redacted", - Self::Deleted => "deleted", - Self::RetentionExpired => "retention_expired", - Self::Unauthorized => "unauthorized", - Self::Locked => "locked", - Self::UnverifiableLegacy => "unverifiable_legacy", - } - } -} - -/// Why an otherwise relevant item was omitted from compact context. -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(rename_all = "snake_case")] -pub enum ContextOmissionReasonV1 { - ByteBudget, - TokenBudget, - Unauthorized, - Redacted, - Deleted, - RetentionExpired, - Locked, - Unavailable, - SummaryHorizonMismatch, - DuplicateRepresentative, -} - -impl ContextOmissionReasonV1 { - pub const fn as_str(self) -> &'static str { - match self { - Self::ByteBudget => "byte_budget", - Self::TokenBudget => "token_budget", - Self::Unauthorized => "unauthorized", - Self::Redacted => "redacted", - Self::Deleted => "deleted", - Self::RetentionExpired => "retention_expired", - Self::Locked => "locked", - Self::Unavailable => "unavailable", - Self::SummaryHorizonMismatch => "summary_horizon_mismatch", - Self::DuplicateRepresentative => "duplicate_representative", - } - } -} - -/// One selected context item. Payload text remains behind the exact anchor. -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] -#[serde(deny_unknown_fields)] -pub struct CompactContextRecordV1 { - pub anchor_id: RetrievalAnchorId, - pub grain: RetrievalGrainV1, - pub hydration: HydrationStateV1, - pub encoded_bytes: u64, -} - -impl CompactContextRecordV1 { - pub fn validate(&self) -> Result<(), SessionContractError> { - self.anchor_id - .validate() - .map_err(|_| SessionContractError::InvalidIdentity { - field: "compact context record anchor", - }) - } -} - -/// One explicit compact-context omission. -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] -#[serde(deny_unknown_fields)] -pub struct CompactContextOmissionV1 { - pub anchor_id: Option, - pub reason: ContextOmissionReasonV1, -} - -impl CompactContextOmissionV1 { - pub fn validate(&self) -> Result<(), SessionContractError> { - if let Some(anchor_id) = &self.anchor_id { - anchor_id - .validate() - .map_err(|_| SessionContractError::InvalidIdentity { - field: "compact context omission anchor", - })?; - } - Ok(()) - } -} - -/// One conflict retained in compact context instead of silently selecting a side. -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] -#[serde(deny_unknown_fields)] -pub struct CompactContextConflictV1 { - pub anchor_id: RetrievalAnchorId, - pub supporting_anchor_ids: BTreeSet, -} - -impl CompactContextConflictV1 { - pub fn validate(&self) -> Result<(), SessionContractError> { - self.anchor_id - .validate() - .map_err(|_| SessionContractError::InvalidIdentity { - field: "compact context conflict anchor", - })?; - for anchor_id in &self.supporting_anchor_ids { - anchor_id - .validate() - .map_err(|_| SessionContractError::InvalidIdentity { - field: "compact context conflict supporting anchor", - })?; - } - Ok(()) - } -} - -/// One typed temporal edge needed to interpret compact-context evolution. -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] -#[serde(deny_unknown_fields)] -pub struct CompactContextLineageEdgeV1 { - pub kind: TemporalAssertionKindV1, - pub subject_anchor_id: RetrievalAnchorId, - pub object_anchor_id: RetrievalAnchorId, - pub knowledge_at: UtcMicros, - pub authority: SessionAuthorityClassV1, - pub authorized: bool, - pub supporting_anchor_ids: BTreeSet, -} - -impl CompactContextLineageEdgeV1 { - pub fn validate(&self) -> Result<(), SessionContractError> { - if self.subject_anchor_id == self.object_anchor_id { - return Err(SessionContractError::AssertionSelfReference); - } - for (field, anchor_id) in [ - ("compact context lineage subject", &self.subject_anchor_id), - ("compact context lineage object", &self.object_anchor_id), - ] { - anchor_id - .validate() - .map_err(|_| SessionContractError::InvalidIdentity { field })?; - } - for anchor_id in &self.supporting_anchor_ids { - anchor_id - .validate() - .map_err(|_| SessionContractError::InvalidIdentity { - field: "compact context lineage supporting anchor", - })?; - } - Ok(()) - } -} - -/// Anchor-only compact-context assembly result. -#[derive(Clone, Debug, Default, Serialize, PartialEq, Eq)] -#[serde(deny_unknown_fields)] -pub struct CompactContextBundleV1 { - pub records: Vec, - pub omissions: Vec, - pub continuation_anchors: Vec, - pub coverage: TemporalCoverageCountsV1, - pub conflicts: Vec, - pub lineage: Vec, - pub encoded_bytes: u64, -} - -impl CompactContextBundleV1 { - pub fn validate(&self) -> Result<(), SessionContractError> { - let mut anchors = BTreeSet::new(); - let mut encoded_bytes = 0_u64; - for record in &self.records { - record.validate()?; - if !anchors.insert(record.anchor_id.clone()) { - return Err(SessionContractError::DuplicateContextAnchor); - } - encoded_bytes = encoded_bytes - .checked_add(record.encoded_bytes) - .ok_or(SessionContractError::CompactContextEncodedBytesOverflow)?; - } - for anchor in &self.continuation_anchors { - anchor - .validate() - .map_err(|_| SessionContractError::InvalidIdentity { - field: "compact context continuation anchor", - })?; - if !anchors.insert(anchor.clone()) { - return Err(SessionContractError::DuplicateContextAnchor); - } - } - for omission in &self.omissions { - omission.validate()?; - if let Some(anchor_id) = &omission.anchor_id - && !anchors.insert(anchor_id.clone()) - { - return Err(SessionContractError::DuplicateContextAnchor); - } - } - for conflict in &self.conflicts { - conflict.validate()?; - } - for edge in &self.lineage { - edge.validate()?; - } - if self.encoded_bytes != encoded_bytes { - return Err(SessionContractError::CompactContextEncodedBytesMismatch); - } - Ok(()) - } -} - -impl<'de> Deserialize<'de> for CompactContextBundleV1 { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - #[derive(Deserialize)] - #[serde(deny_unknown_fields)] - struct Wire { - records: Vec, - omissions: Vec, - continuation_anchors: Vec, - #[serde(default)] - coverage: TemporalCoverageCountsV1, - #[serde(default)] - conflicts: Vec, - #[serde(default)] - lineage: Vec, - encoded_bytes: u64, - } - - let wire = Wire::deserialize(deserializer)?; - let bundle = Self { - records: wire.records, - omissions: wire.omissions, - continuation_anchors: wire.continuation_anchors, - coverage: wire.coverage, - conflicts: wire.conflicts, - lineage: wire.lineage, - encoded_bytes: wire.encoded_bytes, - }; - bundle.validate().map_err(serde::de::Error::custom)?; - Ok(bundle) - } -} - -/// Representative-view counts that complement shard-level [`crate::CoverageReportV1`]. -#[derive( - Clone, Copy, Debug, Default, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash, -)] -#[serde(deny_unknown_fields)] -pub struct TemporalCoverageCountsV1 { - pub visible: u64, - pub hidden: u64, - pub unknown: u64, - pub redacted: u64, -} - -impl TemporalCoverageCountsV1 { - pub const fn total(self) -> Option { - match self.visible.checked_add(self.hidden) { - Some(total) => match total.checked_add(self.unknown) { - Some(total) => total.checked_add(self.redacted), - None => None, - }, - None => None, - } - } - - pub const fn has_withheld_or_unknown(self) -> bool { - self.hidden != 0 || self.unknown != 0 || self.redacted != 0 - } -} - -/// Monotonic provider or projector position for one session source. -#[derive( - Clone, Copy, Debug, Default, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash, -)] -#[serde(transparent)] -pub struct SessionSourceFrontierV1(u64); - -impl SessionSourceFrontierV1 { - pub const fn new(value: u64) -> Self { - Self(value) - } - - pub const fn value(self) -> u64 { - self.0 - } - - pub const fn lag_from(self, target: Self) -> u64 { - target.0.saturating_sub(self.0) - } -} - -/// Closed time interval on one temporal axis. -#[derive(Clone, Copy, Debug, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(deny_unknown_fields)] -pub struct ClosedUtcIntervalV1 { - from_inclusive: Option, - through_inclusive: Option, -} - -impl ClosedUtcIntervalV1 { - pub fn new( - from_inclusive: Option, - through_inclusive: Option, - ) -> Result { - if from_inclusive.is_none() && through_inclusive.is_none() { - return Err(SessionContractError::EmptyCoverageInterval); - } - if matches!( - (from_inclusive, through_inclusive), - (Some(from), Some(through)) if from > through - ) { - return Err(SessionContractError::ReversedCoverageInterval); - } - Ok(Self { - from_inclusive, - through_inclusive, - }) - } - - pub const fn from_inclusive(self) -> Option { - self.from_inclusive - } - - pub const fn through_inclusive(self) -> Option { - self.through_inclusive - } -} - -impl<'de> Deserialize<'de> for ClosedUtcIntervalV1 { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - #[derive(Deserialize)] - #[serde(deny_unknown_fields)] - struct Wire { - from_inclusive: Option, - through_inclusive: Option, - } - - let wire = Wire::deserialize(deserializer)?; - Self::new(wire.from_inclusive, wire.through_inclusive).map_err(serde::de::Error::custom) - } -} - -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(tag = "kind", content = "interval", rename_all = "snake_case")] -pub enum ValidCoverageIntervalV1 { - Known(ClosedUtcIntervalV1), - Unknown, -} - -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(deny_unknown_fields)] -pub struct SessionSourceCoverageIntervalV1 { - pub knowledge: ClosedUtcIntervalV1, - pub valid: ValidCoverageIntervalV1, -} - -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(deny_unknown_fields)] -pub struct SessionTemporalCoverageRequestV1 { - mode: TemporalModeV1, -} - -impl SessionTemporalCoverageRequestV1 { - pub const fn new(mode: TemporalModeV1) -> Self { - Self { mode } - } - - pub const fn mode(&self) -> TemporalModeV1 { - self.mode - } -} - -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(rename_all = "snake_case")] -pub enum SessionSourceCoverageStateV1 { - Fresh, - Stale, - Partial, - Locked, - Redacted, - RetentionWithheld, - Unavailable, -} - -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(tag = "kind", rename_all = "snake_case")] -pub enum SessionSourceCoverageReasonV1 { - CaughtUp, - ProjectionBehindSource { - lag: u64, - }, - SourceBehindTarget { - lag: u64, - }, - ProjectionAndSourceBehind { - projection_lag: u64, - source_lag: u64, - }, - Locked, - Redacted, - RetentionWithheld, - Unavailable, -} - -#[derive(Clone, Debug, Serialize, PartialEq, Eq)] -#[serde(deny_unknown_fields)] -pub struct SessionSourceCoverageV1 { - source_id: SessionSourceIdV1, - observed_frontier: SessionSourceFrontierV1, - committed_frontier: SessionSourceFrontierV1, - target_watermark: SessionSourceFrontierV1, - request: SessionTemporalCoverageRequestV1, - covered_intervals: Vec, - missing_intervals: Vec, - state: SessionSourceCoverageStateV1, - reason: SessionSourceCoverageReasonV1, -} - -impl SessionSourceCoverageV1 { - #[allow(clippy::too_many_arguments)] - pub fn new( - source_id: SessionSourceIdV1, - observed_frontier: SessionSourceFrontierV1, - committed_frontier: SessionSourceFrontierV1, - target_watermark: SessionSourceFrontierV1, - request: SessionTemporalCoverageRequestV1, - mut covered_intervals: Vec, - mut missing_intervals: Vec, - state: SessionSourceCoverageStateV1, - reason: SessionSourceCoverageReasonV1, - ) -> Result { - if committed_frontier > observed_frontier { - return Err(SessionContractError::InvalidSourceCoverageFrontiers); - } - covered_intervals.sort(); - missing_intervals.sort(); - if has_duplicate_intervals(&covered_intervals) - || has_duplicate_intervals(&missing_intervals) - || covered_intervals.iter().any(|covered| { - missing_intervals - .iter() - .any(|missing| coverage_intervals_touch_or_overlap(covered, missing)) - }) - || !coverage_state_matches_reason(state, &reason) - { - return Err(if coverage_state_matches_reason(state, &reason) { - SessionContractError::NonCanonicalCoverageIntervals - } else { - SessionContractError::InvalidSourceCoverageState - }); - } - Ok(Self { - source_id, - observed_frontier, - committed_frontier, - target_watermark, - request, - covered_intervals, - missing_intervals, - state, - reason, - }) - } - - pub fn from_frontiers( - source_id: SessionSourceIdV1, - observed_frontier: SessionSourceFrontierV1, - committed_frontier: SessionSourceFrontierV1, - target_watermark: SessionSourceFrontierV1, - request: SessionTemporalCoverageRequestV1, - ) -> Result { - let projection_lag = committed_frontier.lag_from(observed_frontier); - let source_lag = observed_frontier.lag_from(target_watermark); - let (state, reason) = match (projection_lag, source_lag) { - (0, 0) => ( - SessionSourceCoverageStateV1::Fresh, - SessionSourceCoverageReasonV1::CaughtUp, - ), - (0, lag) => ( - SessionSourceCoverageStateV1::Partial, - SessionSourceCoverageReasonV1::SourceBehindTarget { lag }, - ), - (lag, 0) => ( - SessionSourceCoverageStateV1::Stale, - SessionSourceCoverageReasonV1::ProjectionBehindSource { lag }, - ), - (projection_lag, source_lag) => ( - SessionSourceCoverageStateV1::Partial, - SessionSourceCoverageReasonV1::ProjectionAndSourceBehind { - projection_lag, - source_lag, - }, - ), - }; - Self::new( - source_id, - observed_frontier, - committed_frontier, - target_watermark, - request, - Vec::new(), - Vec::new(), - state, - reason, - ) - } - - pub fn source_id(&self) -> &SessionSourceIdV1 { - &self.source_id - } - - pub const fn observed_frontier(&self) -> SessionSourceFrontierV1 { - self.observed_frontier - } - - pub const fn committed_frontier(&self) -> SessionSourceFrontierV1 { - self.committed_frontier - } - - pub const fn target_watermark(&self) -> SessionSourceFrontierV1 { - self.target_watermark - } - - pub fn request(&self) -> &SessionTemporalCoverageRequestV1 { - &self.request - } - - pub fn covered_intervals(&self) -> &[SessionSourceCoverageIntervalV1] { - &self.covered_intervals - } - - pub fn missing_intervals(&self) -> &[SessionSourceCoverageIntervalV1] { - &self.missing_intervals - } - - pub const fn state(&self) -> SessionSourceCoverageStateV1 { - self.state - } - - pub fn reason(&self) -> &SessionSourceCoverageReasonV1 { - &self.reason - } - - pub const fn frontier_lag(&self) -> u64 { - self.target_watermark - .0 - .saturating_sub(self.committed_frontier.0) - } -} - -impl<'de> Deserialize<'de> for SessionSourceCoverageV1 { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - #[derive(Deserialize)] - #[serde(deny_unknown_fields)] - struct Wire { - source_id: SessionSourceIdV1, - observed_frontier: SessionSourceFrontierV1, - committed_frontier: SessionSourceFrontierV1, - target_watermark: SessionSourceFrontierV1, - request: SessionTemporalCoverageRequestV1, - covered_intervals: Vec, - missing_intervals: Vec, - state: SessionSourceCoverageStateV1, - reason: SessionSourceCoverageReasonV1, - } - - let wire = Wire::deserialize(deserializer)?; - Self::new( - wire.source_id, - wire.observed_frontier, - wire.committed_frontier, - wire.target_watermark, - wire.request, - wire.covered_intervals, - wire.missing_intervals, - wire.state, - wire.reason, - ) - .map_err(serde::de::Error::custom) - } -} - -fn has_duplicate_intervals(intervals: &[SessionSourceCoverageIntervalV1]) -> bool { - intervals.iter().enumerate().any(|(index, left)| { - intervals[index + 1..] - .iter() - .any(|right| coverage_intervals_touch_or_overlap(left, right)) - }) -} - -fn coverage_intervals_touch_or_overlap( - left: &SessionSourceCoverageIntervalV1, - right: &SessionSourceCoverageIntervalV1, -) -> bool { - intervals_touch_or_overlap(left.knowledge, right.knowledge) - && valid_intervals_touch_or_overlap(&left.valid, &right.valid) -} - -fn valid_intervals_touch_or_overlap( - left: &ValidCoverageIntervalV1, - right: &ValidCoverageIntervalV1, -) -> bool { - match (left, right) { - (ValidCoverageIntervalV1::Unknown, ValidCoverageIntervalV1::Unknown) => true, - (ValidCoverageIntervalV1::Known(left), ValidCoverageIntervalV1::Known(right)) => { - intervals_touch_or_overlap(*left, *right) - } - _ => false, - } -} - -fn intervals_touch_or_overlap(left: ClosedUtcIntervalV1, right: ClosedUtcIntervalV1) -> bool { - let left_from = left.from_inclusive.map_or(i64::MIN, |value| value.0); - let left_through = left.through_inclusive.map_or(i64::MAX, |value| value.0); - let right_from = right.from_inclusive.map_or(i64::MIN, |value| value.0); - let right_through = right.through_inclusive.map_or(i64::MAX, |value| value.0); - left_from <= right_through.saturating_add(1) && right_from <= left_through.saturating_add(1) -} - -fn coverage_state_matches_reason( - state: SessionSourceCoverageStateV1, - reason: &SessionSourceCoverageReasonV1, -) -> bool { - matches!( - (state, reason), - ( - SessionSourceCoverageStateV1::Fresh, - SessionSourceCoverageReasonV1::CaughtUp - ) | ( - SessionSourceCoverageStateV1::Stale, - SessionSourceCoverageReasonV1::ProjectionBehindSource { .. } - ) | ( - SessionSourceCoverageStateV1::Partial, - SessionSourceCoverageReasonV1::SourceBehindTarget { .. } - | SessionSourceCoverageReasonV1::ProjectionAndSourceBehind { .. } - ) | ( - SessionSourceCoverageStateV1::Locked, - SessionSourceCoverageReasonV1::Locked - ) | ( - SessionSourceCoverageStateV1::Redacted, - SessionSourceCoverageReasonV1::Redacted - ) | ( - SessionSourceCoverageStateV1::RetentionWithheld, - SessionSourceCoverageReasonV1::RetentionWithheld - ) | ( - SessionSourceCoverageStateV1::Unavailable, - SessionSourceCoverageReasonV1::Unavailable - ) - ) -} - -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(rename_all = "snake_case")] -pub enum SessionSourceCoverageAggregateStateV1 { - Fresh, - Stale, - Partial, -} - -#[derive(Clone, Debug, Serialize, PartialEq, Eq)] -#[serde(deny_unknown_fields)] -pub struct SessionSourceCoverageReceiptV1 { - request: SessionTemporalCoverageRequestV1, - sources: Vec, - aggregate_state: SessionSourceCoverageAggregateStateV1, -} - -impl SessionSourceCoverageReceiptV1 { - pub fn new( - request: SessionTemporalCoverageRequestV1, - mut sources: Vec, - ) -> Result { - if sources.is_empty() { - return Err(SessionContractError::SourceCoverageRequired); - } - sources.sort_by(|left, right| left.source_id.cmp(&right.source_id)); - if sources - .windows(2) - .any(|pair| pair[0].source_id == pair[1].source_id) - { - return Err(SessionContractError::DuplicateSourceCoverage); - } - if sources.iter().any(|source| source.request != request) { - return Err(SessionContractError::SourceCoverageRequestMismatch); - } - let all_fresh = sources - .iter() - .all(|source| source.state == SessionSourceCoverageStateV1::Fresh); - let all_stale = sources - .iter() - .all(|source| source.state == SessionSourceCoverageStateV1::Stale); - let aggregate_state = if all_fresh { - SessionSourceCoverageAggregateStateV1::Fresh - } else if all_stale { - SessionSourceCoverageAggregateStateV1::Stale - } else { - SessionSourceCoverageAggregateStateV1::Partial - }; - Ok(Self { - request, - sources, - aggregate_state, - }) - } - - pub fn request(&self) -> &SessionTemporalCoverageRequestV1 { - &self.request - } - - pub fn sources(&self) -> &[SessionSourceCoverageV1] { - &self.sources - } - - pub const fn aggregate_state(&self) -> SessionSourceCoverageAggregateStateV1 { - self.aggregate_state - } - - pub fn max_frontier_lag(&self) -> u64 { - self.sources - .iter() - .map(SessionSourceCoverageV1::frontier_lag) - .max() - .unwrap_or(0) - } -} - -impl<'de> Deserialize<'de> for SessionSourceCoverageReceiptV1 { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - #[derive(Deserialize)] - #[serde(deny_unknown_fields)] - struct Wire { - request: SessionTemporalCoverageRequestV1, - sources: Vec, - aggregate_state: SessionSourceCoverageAggregateStateV1, - } - - let wire = Wire::deserialize(deserializer)?; - let receipt = Self::new(wire.request, wire.sources).map_err(serde::de::Error::custom)?; - if receipt.aggregate_state != wire.aggregate_state { - return Err(serde::de::Error::custom( - SessionContractError::InvalidSourceCoverageState, - )); - } - Ok(receipt) - } -} - -#[derive(Clone, Debug, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[serde(deny_unknown_fields)] -pub struct SessionRefreshSourceTargetV1 { - source_id: SessionSourceIdV1, - observed_frontier: SessionSourceFrontierV1, - target_watermark: SessionSourceFrontierV1, -} - -impl SessionRefreshSourceTargetV1 { - pub fn new( - source_id: SessionSourceIdV1, - observed_frontier: SessionSourceFrontierV1, - target_watermark: SessionSourceFrontierV1, - ) -> Result { - if target_watermark < observed_frontier { - return Err(SessionContractError::InvalidRefreshSourceFrontier); - } - Ok(Self { - source_id, - observed_frontier, - target_watermark, - }) - } - - pub fn source_id(&self) -> &SessionSourceIdV1 { - &self.source_id - } - - pub const fn observed_frontier(&self) -> SessionSourceFrontierV1 { - self.observed_frontier - } - - pub const fn target_watermark(&self) -> SessionSourceFrontierV1 { - self.target_watermark - } -} - -impl<'de> Deserialize<'de> for SessionRefreshSourceTargetV1 { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - #[derive(Deserialize)] - #[serde(deny_unknown_fields)] - struct Wire { - source_id: SessionSourceIdV1, - observed_frontier: SessionSourceFrontierV1, - target_watermark: SessionSourceFrontierV1, - } - - let wire = Wire::deserialize(deserializer)?; - Self::new( - wire.source_id, - wire.observed_frontier, - wire.target_watermark, - ) - .map_err(serde::de::Error::custom) - } -} - -#[derive(Clone, Debug, Serialize, PartialEq, Eq, Hash)] -#[serde(deny_unknown_fields)] -pub struct SessionRefreshKeyV1 { - store_root_id: String, - session_id: SessionId, - sources: Vec, - projector_version: String, - configuration_digest: String, -} - -impl SessionRefreshKeyV1 { - pub fn new( - store_root_id: impl Into, - session_id: SessionId, - mut sources: Vec, - projector_version: impl Into, - configuration_digest: impl Into, - ) -> Result { - let store_root_id = canonical_component(store_root_id.into(), "store_root_id")?; - let projector_version = canonical_component(projector_version.into(), "projector_version")?; - let configuration_digest = - canonical_component(configuration_digest.into(), "configuration_digest")?; - if sources.is_empty() { - return Err(SessionContractError::RefreshSourcesRequired); - } - sources.sort(); - if sources - .windows(2) - .any(|pair| pair[0].source_id == pair[1].source_id) - { - return Err(SessionContractError::DuplicateRefreshSource); - } - Ok(Self { - store_root_id, - session_id, - sources, - projector_version, - configuration_digest, - }) - } - - pub fn sources(&self) -> &[SessionRefreshSourceTargetV1] { - &self.sources - } - - pub fn store_root_id(&self) -> &str { - &self.store_root_id - } - - pub fn session_id(&self) -> &SessionId { - &self.session_id - } - - pub fn projector_version(&self) -> &str { - &self.projector_version - } - - pub fn configuration_digest(&self) -> &str { - &self.configuration_digest - } -} - -impl<'de> Deserialize<'de> for SessionRefreshKeyV1 { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - #[derive(Deserialize)] - #[serde(deny_unknown_fields)] - struct Wire { - store_root_id: String, - session_id: SessionId, - sources: Vec, - projector_version: String, - configuration_digest: String, - } - - let wire = Wire::deserialize(deserializer)?; - Self::new( - wire.store_root_id, - wire.session_id, - wire.sources, - wire.projector_version, - wire.configuration_digest, - ) - .map_err(serde::de::Error::custom) - } -} - -fn canonical_component(value: String, field: &'static str) -> Result { - if value.is_empty() - || value.trim() != value - || value.len() > 512 - || value.chars().any(char::is_control) - { - return Err(SessionContractError::InvalidIdentity { field }); - } - Ok(value) -} - -#[cfg(test)] -mod source_freshness_tests { - use super::*; - - fn source(value: &str) -> SessionSourceIdV1 { - SessionSourceIdV1::new(value).unwrap() - } - - #[test] - fn validity_intervals_reject_empty_and_reversed_bounds() { - assert_eq!( - ClosedUtcIntervalV1::new(None, None), - Err(SessionContractError::EmptyCoverageInterval) - ); - assert_eq!( - ClosedUtcIntervalV1::new(Some(UtcMicros(20)), Some(UtcMicros(10))), - Err(SessionContractError::ReversedCoverageInterval) - ); - - let request = SessionTemporalCoverageRequestV1::new(TemporalModeV1::Current); - let interval = |from, through| SessionSourceCoverageIntervalV1 { - knowledge: ClosedUtcIntervalV1::new(Some(UtcMicros(from)), Some(UtcMicros(through))) - .unwrap(), - valid: ValidCoverageIntervalV1::Unknown, - }; - assert_eq!( - SessionSourceCoverageV1::new( - source("cursor"), - SessionSourceFrontierV1::new(10), - SessionSourceFrontierV1::new(10), - SessionSourceFrontierV1::new(10), - request, - vec![interval(1, 5), interval(6, 10)], - Vec::new(), - SessionSourceCoverageStateV1::Fresh, - SessionSourceCoverageReasonV1::CaughtUp, - ), - Err(SessionContractError::NonCanonicalCoverageIntervals) - ); - } - - #[test] - fn source_freshness_is_derived_from_observed_projected_and_target_frontiers() { - let request = SessionTemporalCoverageRequestV1::new(TemporalModeV1::Current); - let stale = SessionSourceCoverageV1::from_frontiers( - source("cursor"), - SessionSourceFrontierV1::new(10), - SessionSourceFrontierV1::new(8), - SessionSourceFrontierV1::new(10), - request.clone(), - ) - .unwrap(); - assert_eq!(stale.state(), SessionSourceCoverageStateV1::Stale); - assert_eq!( - stale.reason(), - &SessionSourceCoverageReasonV1::ProjectionBehindSource { lag: 2 } - ); - - let partial = SessionSourceCoverageV1::from_frontiers( - source("claude"), - SessionSourceFrontierV1::new(8), - SessionSourceFrontierV1::new(8), - SessionSourceFrontierV1::new(10), - request, - ) - .unwrap(); - assert_eq!(partial.state(), SessionSourceCoverageStateV1::Partial); - assert_eq!( - partial.reason(), - &SessionSourceCoverageReasonV1::SourceBehindTarget { lag: 2 } - ); - } - - #[test] - fn aggregate_receipt_preserves_sources_and_mixed_freshness() { - let request = SessionTemporalCoverageRequestV1::new(TemporalModeV1::Current); - let receipt = SessionSourceCoverageReceiptV1::new( - request.clone(), - vec![ - SessionSourceCoverageV1::from_frontiers( - source("cursor"), - SessionSourceFrontierV1::new(10), - SessionSourceFrontierV1::new(10), - SessionSourceFrontierV1::new(10), - request.clone(), - ) - .unwrap(), - SessionSourceCoverageV1::from_frontiers( - source("claude"), - SessionSourceFrontierV1::new(10), - SessionSourceFrontierV1::new(7), - SessionSourceFrontierV1::new(10), - request, - ) - .unwrap(), - ], - ) - .unwrap(); - - assert_eq!(receipt.sources().len(), 2); - assert_eq!( - receipt.aggregate_state(), - SessionSourceCoverageAggregateStateV1::Partial - ); - assert_eq!(receipt.max_frontier_lag(), 3); - } - - #[test] - fn refresh_key_canonicalizes_sources_and_round_trips() { - let target = |name: &str| { - SessionRefreshSourceTargetV1::new( - source(name), - SessionSourceFrontierV1::new(8), - SessionSourceFrontierV1::new(10), - ) - .unwrap() - }; - let key = SessionRefreshKeyV1::new( - "root.1", - SessionId::new("session.1").unwrap(), - vec![target("cursor"), target("claude")], - "projector.v1", - "sha256:configuration", - ) - .unwrap(); - assert_eq!(key.sources()[0].source_id().as_str(), "claude"); - let encoded = serde_json::to_string(&key).unwrap(); - assert_eq!( - serde_json::from_str::(&encoded).unwrap(), - key - ); - } -} diff --git a/crates/tracedecay-query/src/search_quality/packaged.rs b/crates/tracedecay-query/src/search_quality/packaged.rs index 2af1f78322..2584fcd2eb 100644 --- a/crates/tracedecay-query/src/search_quality/packaged.rs +++ b/crates/tracedecay-query/src/search_quality/packaged.rs @@ -19,93 +19,87 @@ const FILES: &[(&str, &[u8])] = &[ ( WORKLOAD_PATH, include_bytes!( - "../../assets/runtime-root/tests/fixtures/search_quality/query-lexical-graph-workload-v1.json" + "../../../../tests/fixtures/search_quality/query-lexical-graph-workload-v1.json" ), ), ( "tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/time.rs", include_bytes!( - "../../assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/time.rs" + "../../../../tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/time.rs" ), ), ( "tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/watermark.rs", include_bytes!( - "../../assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/watermark.rs" + "../../../../tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/watermark.rs" ), ), ( "tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/canonical.rs", include_bytes!( - "../../assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/canonical.rs" + "../../../../tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/canonical.rs" ), ), ( "tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/error.rs", include_bytes!( - "../../assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/error.rs" + "../../../../tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/error.rs" ), ), ( "tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/coverage.rs", include_bytes!( - "../../assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/coverage.rs" + "../../../../tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/coverage.rs" ), ), ( "tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/repository.rs", include_bytes!( - "../../assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/repository.rs" + "../../../../tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/repository.rs" ), ), ( "tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/integration.rs", include_bytes!( - "../../assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/integration.rs" + "../../../../tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/integration.rs" ), ), ( "tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/session.rs", include_bytes!( - "../../assets/runtime-root/tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/session.rs" + "../../../../tests/fixtures/search_quality/corpus/crates/tracedecay-domain/src/session.rs" ), ), ( "tests/fixtures/context_eval_project/src/auth/login.rs", - include_bytes!( - "../../assets/runtime-root/tests/fixtures/context_eval_project/src/auth/login.rs" - ), + include_bytes!("../../../../tests/fixtures/context_eval_project/src/auth/login.rs"), ), ( "tests/fixtures/context_eval_project/src/auth/session.rs", - include_bytes!( - "../../assets/runtime-root/tests/fixtures/context_eval_project/src/auth/session.rs" - ), + include_bytes!("../../../../tests/fixtures/context_eval_project/src/auth/session.rs"), ), ( "tests/fixtures/context_eval_project/src/storage/config_store.rs", include_bytes!( - "../../assets/runtime-root/tests/fixtures/context_eval_project/src/storage/config_store.rs" + "../../../../tests/fixtures/context_eval_project/src/storage/config_store.rs" ), ), ( "tests/fixtures/context_eval_project/src/net/retry.rs", - include_bytes!( - "../../assets/runtime-root/tests/fixtures/context_eval_project/src/net/retry.rs" - ), + include_bytes!("../../../../tests/fixtures/context_eval_project/src/net/retry.rs"), ), ( "tests/fixtures/sample.dockerfile", - include_bytes!("../../assets/runtime-root/tests/fixtures/sample.dockerfile"), + include_bytes!("../../../../tests/fixtures/sample.dockerfile"), ), ( "evals/agent_adoption/fixture/Cargo.lock", - include_bytes!("../../assets/runtime-root/evals/agent_adoption/fixture/Cargo.lock"), + include_bytes!("../../../../evals/agent_adoption/fixture/Cargo.lock"), ), ( "tests/fixtures/search_quality/corpus/cargo-slot/src/main.rust.fixture", include_bytes!( - "../../assets/runtime-root/tests/fixtures/search_quality/corpus/cargo-slot/src/main.rust.fixture" + "../../../../tests/fixtures/search_quality/corpus/cargo-slot/src/main.rust.fixture" ), ), ]; diff --git a/crates/tracedecay-search-eval/src/packaged_assets.rs b/crates/tracedecay-search-eval/src/packaged_assets.rs index 90083d8974..f1bd8e69cd 100644 --- a/crates/tracedecay-search-eval/src/packaged_assets.rs +++ b/crates/tracedecay-search-eval/src/packaged_assets.rs @@ -166,6 +166,12 @@ pub(crate) fn admitted_scope(_root: &Path) -> Option { #[cfg(test)] mod tests { + use std::collections::BTreeMap; + + use tracedecay_query::search_quality::{ + DirectEvaluationStatusV1, QUERY_BASELINE_PROFILE, packaged, + }; + /// The packaged evaluator carries its own workload, corpus, and Git /// authority, so `compare` needs nothing from the checkout it runs in. #[test] @@ -187,4 +193,92 @@ mod tests { ] ); } + + #[test] + fn source_and_packaged_evaluations_preserve_corpus_and_fallback_receipts() { + let assets = super::materialize().expect("materialized evaluator fixture"); + assert!(crate::root_admitted_corpus_scope(assets.root()).is_none()); + assert!( + tracedecay_runtime_core::storage::write_repository_identity_marker( + assets.root(), + "project.search-eval-source-fixture", + ) + .expect("enroll the temporary evaluator repository") + ); + let scope = crate::root_admitted_corpus_scope(assets.root()) + .expect("source evaluation admits the fixture's authoritative identity"); + assert_eq!( + scope.project_id.as_str(), + "project.search-eval-source-fixture" + ); + + let profiles = vec![QUERY_BASELINE_PROFILE.to_owned()]; + let source = crate::compare_direct( + assets.root(), + Some(&assets.workload_path()), + Some(&profiles), + crate::root_admitted_corpus_scope, + ) + .expect("source-backed evaluator execution"); + let packaged = + crate::compare_default_direct(Some(&profiles)).expect("packaged evaluator execution"); + + assert_eq!(source.workload_digest, packaged::WORKLOAD_SHA256); + assert_eq!(source.workload_digest, packaged.workload_digest); + assert_eq!(source.corpus_digest, packaged.corpus_digest); + assert_eq!(source.execution_contract, packaged.execution_contract); + assert_eq!( + source.profile_material_digests, + packaged.profile_material_digests + ); + + let workload = assets.workload(); + let expected_receipts = workload + .expected_query_fallback_digests + .iter() + .collect::>(); + for report in [&source, &packaged] { + assert_eq!(report.command, "compare"); + assert_eq!(report.status, DirectEvaluationStatusV1::Fail); + assert_eq!( + report.fixture_source_repository_commit, + workload.source_repository_commit + ); + assert_eq!( + report.fixture_source_repository_tree, + workload.source_repository_tree + ); + assert!( + report + .profiles + .iter() + .any(|profile| profile.failed_queries > 0) + ); + assert_eq!(report.profiles.len(), expected_receipts.len()); + for profile in &report.profiles { + assert_eq!(profile.profile_id, QUERY_BASELINE_PROFILE); + assert!(profile.fallback_stable); + assert!(profile.fallback_matches_expected); + } + + let observed_receipts = report + .raw_outputs + .iter() + .map(|output| { + assert_eq!(output.profile_id, QUERY_BASELINE_PROFILE); + assert_eq!(output.workload_digest, report.workload_digest); + assert_eq!(output.corpus_digest, report.corpus_digest); + assert!(output.query_fallback_matches_expected); + assert_eq!(output.fallback_digest, output.query_fallback_digest); + assert_eq!( + output.query_fallback_digest, + output.expected_query_fallback_digest + ); + (&output.partition, &output.query_fallback_digest) + }) + .collect::>(); + assert_eq!(observed_receipts.len(), report.raw_outputs.len()); + assert_eq!(observed_receipts, expected_receipts); + } + } } diff --git a/crates/tracedecay-search-eval/src/report_tests.rs b/crates/tracedecay-search-eval/src/report_tests.rs index 3814a65551..dff9d1af9b 100644 --- a/crates/tracedecay-search-eval/src/report_tests.rs +++ b/crates/tracedecay-search-eval/src/report_tests.rs @@ -49,7 +49,7 @@ fn assert_baseline_report_retains_raw_fallback_current_and_exact_ten_x_samples( profile.fallback_matches_expected, "{}:{} ranking receipt drifted from \ `expected_query_fallback_digests.{}` in \ - crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/query-lexical-graph-workload-v1.json \ + tests/fixtures/search_quality/query-lexical-graph-workload-v1.json \ ({observed}). The receipt binds ordered ranking rows and lane coverage, \ not generation or extractor-revision identity. Re-pin only that receipt \ when the ranking itself changed; do not touch the workload identity pin.", diff --git a/evals/agent_adoption/BUILD.bazel b/evals/agent_adoption/BUILD.bazel index f9f95ae7e9..c2c307da98 100644 --- a/evals/agent_adoption/BUILD.bazel +++ b/evals/agent_adoption/BUILD.bazel @@ -18,3 +18,11 @@ py_test( legacy_create_init = 0, main = "selftest.py", ) + +# BEGIN generated by scripts/bazel/gen_builds.py +filegroup( + name = "fixture", + srcs = glob(["fixture/**"]), + visibility = ["//visibility:public"], +) +# END generated by scripts/bazel/gen_builds.py diff --git a/scripts/bazel/gen_builds.py b/scripts/bazel/gen_builds.py index 366be494d0..c68a96cda9 100755 --- a/scripts/bazel/gen_builds.py +++ b/scripts/bazel/gen_builds.py @@ -211,6 +211,20 @@ NO_DEFAULT_FEATURES = "!no-default-features" +def owner_pkg(repo_rel, repo=REPO): + """Honor existing Bazel package boundaries before creating a shared package.""" + for directory in (repo_rel.parent, *repo_rel.parent.parents): + if directory == Path("."): + break + if any((repo / directory / name).is_file() for name in ("BUILD.bazel", "BUILD")): + group = repo_rel.parent.relative_to(directory) + return directory.as_posix(), "" if group == Path(".") else group.as_posix() + parts = repo_rel.parts + if parts[0] == "crates": + return "/".join(parts[:2]), "/".join(parts[2:-1]) + return parts[0], "/".join(parts[1:-1]) + + def normalize_default_alias(feats, feature_table): """Add `default` when it is only an alias for features already enabled. @@ -758,14 +772,6 @@ def srcs_expr(fragments): # shared between member crates) need a filegroup in their own package. out_of_pkg = {} # (top_dir, group_dir) -> set of crate_root paths in package - def owner_pkg(repo_rel): - """Package dir that owns repo_rel plus the group dir inside it. Crates - members own their subtree. Other top-level dirs own theirs.""" - parts = repo_rel.parts - if parts[0] == "crates": - return "/".join(parts[:2]), "/".join(parts[2:-1]) - return parts[0], "/".join(parts[1:-1]) - def group_label(repo_rel, *, sources=False): """filegroup label + pkg-relative file label for an out-of-package file, registering the group for emission in the owning package.""" @@ -1411,7 +1417,7 @@ def package_rules(pkg_dir, exports): name member crate roots, so they need none.""" rules = [] for gname, entry in sorted(by_pkg.get(pkg_dir, {}).items()): - pattern = entry.get("pattern", f'{entry["glob"]}/**') + pattern = entry.get("pattern", f'{entry["glob"]}/**' if entry["glob"] else "**") exclude = "" if entry.get("sources"): pattern += "/*.rs" @@ -1531,6 +1537,8 @@ def render_shared(path, pkg_dir): # other members reach into this one's subtree for. outputs[path] += "\n" + "\n\n".join(package_rules(pkg_dir, False)) + "\n" continue + if not path.exists() and path.with_name("BUILD").is_file(): + path = path.with_name("BUILD") rendered = render_shared(path, pkg_dir) if rendered is None: obsolete.append(path) diff --git a/scripts/test-gen-builds-default-alias.py b/scripts/test-gen-builds-default-alias.py index 5dadadb25b..6154dc268e 100755 --- a/scripts/test-gen-builds-default-alias.py +++ b/scripts/test-gen-builds-default-alias.py @@ -101,5 +101,40 @@ def test_suite_owns_its_inputs_and_explicit_shared_modules(self) -> None: self.assertEqual(sources, {root / "tests/owned/main.rs"}) +class SharedPackageOwnershipTests(unittest.TestCase): + def test_nested_package_owns_embedded_fixture(self) -> None: + gen = load_gen_builds() + with tempfile.TemporaryDirectory() as scratch: + root = Path(scratch) + package = root / "evals/agent_adoption" + package.mkdir(parents=True) + (root / "evals/BUILD.bazel").write_text("# generated parent") + for build_name in ("BUILD.bazel", "BUILD"): + build = package / build_name + build.write_text("# handwritten package") + self.assertEqual( + gen.owner_pkg(Path("evals/agent_adoption/fixture/Cargo.lock"), root), + ("evals/agent_adoption", "fixture"), + ) + self.assertEqual( + gen.owner_pkg(Path("evals/agent_adoption/input.json"), root), + ("evals/agent_adoption", ""), + ) + build.unlink() + + def test_unowned_fixtures_keep_shared_package_layout(self) -> None: + gen = load_gen_builds() + with tempfile.TemporaryDirectory() as scratch: + root = Path(scratch) + self.assertEqual( + gen.owner_pkg(Path("tests/fixtures/example.json"), root), + ("tests", "fixtures"), + ) + self.assertEqual( + gen.owner_pkg(Path("crates/example/tests/input.json"), root), + ("crates/example", "tests"), + ) + + if __name__ == "__main__": unittest.main() diff --git a/tests/BUILD.bazel b/tests/BUILD.bazel index ddda3cb21f..ead60ab383 100644 --- a/tests/BUILD.bazel +++ b/tests/BUILD.bazel @@ -22,6 +22,36 @@ exports_files(["fixtures/claude-schemas/hooks.schema.json", "fixtures/claude-sch visibility = ["//visibility:public"], ) +filegroup( + name = "fixtures_context_eval_project_src_auth", + srcs = glob(["fixtures/context_eval_project/src/auth/**"]), + visibility = ["//visibility:public"], +) + +exports_files(["fixtures/context_eval_project/src/auth/login.rs", "fixtures/context_eval_project/src/auth/session.rs"], + visibility = ["//visibility:public"], +) + +filegroup( + name = "fixtures_context_eval_project_src_net", + srcs = glob(["fixtures/context_eval_project/src/net/**"]), + visibility = ["//visibility:public"], +) + +exports_files(["fixtures/context_eval_project/src/net/retry.rs"], + visibility = ["//visibility:public"], +) + +filegroup( + name = "fixtures_context_eval_project_src_storage", + srcs = glob(["fixtures/context_eval_project/src/storage/**"]), + visibility = ["//visibility:public"], +) + +exports_files(["fixtures/context_eval_project/src/storage/config_store.rs"], + visibility = ["//visibility:public"], +) + filegroup( name = "fixtures_cursor-schemas", srcs = glob(["fixtures/cursor-schemas/**"]), @@ -222,6 +252,46 @@ exports_files(["fixtures/remote_tls/alternate-root.crt.pem", "fixtures/remote_tl visibility = ["//visibility:public"], ) +filegroup( + name = "fixtures_search_quality", + srcs = glob(["fixtures/search_quality/**"]), + visibility = ["//visibility:public"], +) + +exports_files(["fixtures/search_quality/query-lexical-graph-workload-v1.json"], + visibility = ["//visibility:public"], +) + +filegroup( + name = "fixtures_search_quality_corpus_cargo-slot_src", + srcs = glob(["fixtures/search_quality/corpus/cargo-slot/src/**"]), + visibility = ["//visibility:public"], +) + +exports_files(["fixtures/search_quality/corpus/cargo-slot/src/main.rust.fixture"], + visibility = ["//visibility:public"], +) + +filegroup( + name = "fixtures_search_quality_corpus_crates_tracedecay-domain_src", + srcs = glob(["fixtures/search_quality/corpus/crates/tracedecay-domain/src/**"]), + visibility = ["//visibility:public"], +) + +exports_files(["fixtures/search_quality/corpus/crates/tracedecay-domain/src/integration.rs", "fixtures/search_quality/corpus/crates/tracedecay-domain/src/repository.rs", "fixtures/search_quality/corpus/crates/tracedecay-domain/src/session.rs"], + visibility = ["//visibility:public"], +) + +filegroup( + name = "fixtures_search_quality_corpus_crates_tracedecay-domain_src_research", + srcs = glob(["fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/**"]), + visibility = ["//visibility:public"], +) + +exports_files(["fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/canonical.rs", "fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/coverage.rs", "fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/error.rs", "fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/time.rs", "fixtures/search_quality/corpus/crates/tracedecay-domain/src/research/watermark.rs"], + visibility = ["//visibility:public"], +) + filegroup( name = "fixtures_transcript_golden_cline_like", srcs = glob(["fixtures/transcript_golden/cline_like/**"]), @@ -268,7 +338,7 @@ filegroup( visibility = ["//visibility:public"], ) -exports_files(["fixtures/context_eval_labeled.json", "fixtures/message_search_eval_labeled.json"], +exports_files(["fixtures/context_eval_labeled.json", "fixtures/message_search_eval_labeled.json", "fixtures/sample.dockerfile"], visibility = ["//visibility:public"], ) diff --git a/crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/query-lexical-graph-workload-v1.json b/tests/fixtures/search_quality/query-lexical-graph-workload-v1.json similarity index 100% rename from crates/tracedecay-query/assets/runtime-root/tests/fixtures/search_quality/query-lexical-graph-workload-v1.json rename to tests/fixtures/search_quality/query-lexical-graph-workload-v1.json From 92a2c31c8737273b7fc349dd1c8dbef4b3b551e1 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Mon, 26 Oct 2026 08:58:10 +0000 Subject: [PATCH 6/8] fix(source-edit): place MoveSymbol imports at syntax boundaries Restack unique #4531 onto the rewritten #4530 tip. --- .../src/edits/execute_tests.rs | 95 ++++++++++++++++++- .../tracedecay-source-edit/src/edits/mod.rs | 4 +- .../src/edits/preview.rs | 47 +++------ .../src/move_symbol/mod.rs | 7 +- 4 files changed, 111 insertions(+), 42 deletions(-) diff --git a/crates/tracedecay-source-edit/src/edits/execute_tests.rs b/crates/tracedecay-source-edit/src/edits/execute_tests.rs index f1e11c8cc5..be4829064e 100644 --- a/crates/tracedecay-source-edit/src/edits/execute_tests.rs +++ b/crates/tracedecay-source-edit/src/edits/execute_tests.rs @@ -346,12 +346,22 @@ fn assert_import_fixture_compiles(project: &Path) { ); } +const MARKER_DESTINATION: &str = "pub fn marker() {}\n"; + async fn assert_move_import_ownership(import: &str, binding: &str, preserve: bool) { + assert_move_into_destination(import, binding, preserve, MARKER_DESTINATION).await; +} + +async fn assert_move_into_destination( + import: &str, + binding: &str, + preserve: bool, + original_destination: &str, +) { let project = tempdir().unwrap(); fs::create_dir_all(project.path().join("src")).unwrap(); let moved_symbol = format!("pub fn moved(value: {binding}) -> {binding} {{\n value\n}}"); let original_source = format!("{import}\n\n{moved_symbol}\n\npub fn remains() {{}}\n"); - let original_destination = "pub fn marker() {}\n"; // This module never refers to `moved`; its dependency on the original // export path must survive moving that function to a different module. let consumer_type = if preserve { @@ -510,6 +520,89 @@ async fn move_symbol_still_removes_an_unused_private_import() { assert_move_import_ownership("use crate::model::Widget;", "Widget", false).await; } +#[tokio::test] +async fn move_symbol_inserts_imports_after_a_multiline_use_group() { + assert_move_into_destination( + "use crate::model::Widget;", + "Widget", + false, + "use std::{\n fmt::Debug,\n};\n\npub fn marker(_: &dyn Debug) {}\n", + ) + .await; +} + +#[tokio::test] +async fn move_symbol_preserves_an_outer_attribute_after_a_same_line_import() { + assert_move_into_destination( + "use crate::model::Widget;", + "Widget", + false, + "use std::fmt::Debug; #[cfg(any())]\npub fn marker(_: &dyn Debug) {}\n", + ) + .await; +} + +#[tokio::test] +async fn move_symbol_inserts_imports_after_module_inner_attributes() { + assert_move_into_destination( + "use crate::model::Widget;", + "Widget", + false, + "#![allow(dead_code)]\npub fn marker() {}\n", + ) + .await; +} + +#[tokio::test] +async fn move_symbol_refuses_a_destination_that_does_not_parse() { + let project = tempdir().unwrap(); + fs::create_dir_all(project.path().join("src")).unwrap(); + let source = + "use crate::model::Widget;\n\npub fn moved(value: Widget) -> Widget {\n value\n}\n"; + let broken = "pub fn marker( {\n"; + for (path, content) in [ + ("src/api.rs", source), + ("src/model.rs", "pub struct Widget;\n"), + ("src/relocated.rs", broken), + ] { + fs::write(project.path().join(path), content).unwrap(); + } + let (graph, _) = fixture_graph(project.path()).await; + let code_graph = fixture_symbol_code_graph( + "src/api.rs", + source, + "pub fn moved(value: Widget) -> Widget {\n value\n}", + "moved", + "api::moved", + ); + let request = fixture_request_for_edit( + SourceEditRequest::MoveSymbol { + symbol: "moved".to_owned(), + dest_file: "src/relocated.rs".to_owned(), + dry_run: true, + update_references: false, + }, + "source-edit.move-unparseable-destination", + ); + let outcome = resolve_source_edit_preview( + &graph, + &code_graph, + &request.context, + request.observed_at, + request_graph_cancellation(&request.context), + request.edit.clone(), + ) + .await; + assert!( + outcome.is_err() || !outcome.unwrap().outcome.success(), + "an unparseable destination must refuse the move" + ); + assert_eq!( + fs::read_to_string(project.path().join("src/relocated.rs")).unwrap(), + broken + ); +} + #[tokio::test] async fn move_symbol_preserves_a_destination_created_at_publication() { let project = tempdir().unwrap(); diff --git a/crates/tracedecay-source-edit/src/edits/mod.rs b/crates/tracedecay-source-edit/src/edits/mod.rs index aaeea9e24b..9fdb30eb60 100644 --- a/crates/tracedecay-source-edit/src/edits/mod.rs +++ b/crates/tracedecay-source-edit/src/edits/mod.rs @@ -18,8 +18,8 @@ mod test_support; pub(crate) use ast_grep::ast_grep_rewrite; pub(crate) use preview::{ - LeadingKind, MAX_PREVIEW_DIFF_LINES, PREVIEW_DIFF_CONTEXT, bounded_region_diff, - classify_leading_line, edit_success_message, + MAX_PREVIEW_DIFF_LINES, PREVIEW_DIFF_CONTEXT, bounded_region_diff, edit_success_message, + is_inner_doc_line, }; pub(crate) use primitives::{ insert_at, insert_at_symbol, multi_str_replace, replace_symbol, splice_lines, str_replace, diff --git a/crates/tracedecay-source-edit/src/edits/preview.rs b/crates/tracedecay-source-edit/src/edits/preview.rs index d2227df442..11ce2e0035 100644 --- a/crates/tracedecay-source-edit/src/edits/preview.rs +++ b/crates/tracedecay-source-edit/src/edits/preview.rs @@ -53,6 +53,12 @@ pub(crate) fn classify_leading_line(line: &str) -> LeadingKind { } } +/// True for a `//!` inner module-doc line, which documents the enclosing +/// module and can never belong to a moved item. +pub(crate) fn is_inner_doc_line(line: &str) -> bool { + classify_leading_line(line) == LeadingKind::InnerDoc +} + /// Unchanged context lines shown on each side of the changed region in a /// dry-run preview diff. pub(crate) const PREVIEW_DIFF_CONTEXT: usize = 3; @@ -142,43 +148,14 @@ pub(crate) fn bounded_region_diff( #[cfg(test)] mod tests { - use super::{LeadingKind, bounded_region_diff, classify_leading_line}; + use super::{bounded_region_diff, is_inner_doc_line}; #[test] - fn classify_leading_line_covers_every_kind() { - assert_eq!(classify_leading_line(""), LeadingKind::Blank); - assert_eq!(classify_leading_line(" \t"), LeadingKind::Blank); - assert_eq!(classify_leading_line("//! inner"), LeadingKind::InnerDoc); - assert_eq!(classify_leading_line("/// outer"), LeadingKind::OuterDoc); - assert_eq!( - classify_leading_line("/** block doc */"), - LeadingKind::OuterDoc - ); - assert_eq!(classify_leading_line("// plain"), LeadingKind::LineComment); - assert_eq!( - classify_leading_line("/* block */"), - LeadingKind::BlockComment - ); - assert_eq!(classify_leading_line("#[inline]"), LeadingKind::Attribute); - assert_eq!( - classify_leading_line("#![allow(dead_code)]"), - LeadingKind::Attribute - ); - assert_eq!( - classify_leading_line("use crate::x;"), - LeadingKind::UseImport - ); - assert_eq!( - classify_leading_line("pub use crate::x;"), - LeadingKind::UseImport - ); - assert_eq!( - classify_leading_line("extern crate foo;"), - LeadingKind::UseImport - ); - assert_eq!(classify_leading_line("fn f() {}"), LeadingKind::Code); - // Leading whitespace never changes the classification. - assert_eq!(classify_leading_line(" //! inner"), LeadingKind::InnerDoc); + fn inner_doc_lines_are_recognized_regardless_of_indent() { + assert!(is_inner_doc_line("//! inner")); + assert!(is_inner_doc_line(" //! inner")); + assert!(!is_inner_doc_line("/// outer")); + assert!(!is_inner_doc_line("// plain")); } #[test] diff --git a/crates/tracedecay-source-edit/src/move_symbol/mod.rs b/crates/tracedecay-source-edit/src/move_symbol/mod.rs index 9d5b50c0f4..c650a12e4c 100644 --- a/crates/tracedecay-source-edit/src/move_symbol/mod.rs +++ b/crates/tracedecay-source-edit/src/move_symbol/mod.rs @@ -26,8 +26,8 @@ use tracedecay_domain::errors::{Result, TraceDecayError}; use tracedecay_graph_query::{map_code_graph_read_runtime_error, map_projection_error}; use crate::edits::{ - EditSymbolV1, LeadingKind, classify_leading_line, edit_success_message, - edit_symbol_from_summary, resolve_symbol_for_edit, splice_lines, + EditSymbolV1, edit_success_message, edit_symbol_from_summary, is_inner_doc_line, + resolve_symbol_for_edit, splice_lines, }; use fs_guards::{ @@ -130,8 +130,7 @@ pub(crate) async fn move_symbol( // module, not the following item. Advance past it so the source keeps its // module doc and the destination doesn't receive a stray `//!` mid-file // (a hard E0753). - while start < end_inclusive && classify_leading_line(src_lines[start]) == LeadingKind::InnerDoc - { + while start < end_inclusive && is_inner_doc_line(src_lines[start]) { start += 1; } let moved_text = src_lines[start..=end_inclusive].join("\n"); From 1e4aa827b196e63addd7c8ec002b52baf2a288fd Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Mon, 26 Oct 2026 08:58:15 +0000 Subject: [PATCH 7/8] fix(mcp): keep tool descriptions free of runtime state Restack unique #4529 onto the rewritten #4531 tip. --- .../tests/core_cli_suite/cli_boundary.rs | 18 +-- .../tracedecay-mcp-catalog/src/definitions.rs | 59 +------- .../src/definitions/tests.rs | 58 ++------ crates/tracedecay-mcp-catalog/src/lib.rs | 8 +- crates/tracedecay-mcp/src/lib.rs | 7 +- crates/tracedecay-mcp/src/tools/binding.rs | 8 +- .../src/tools/catalog_discovery.rs | 134 +++++------------- crates/tracedecay/src/daemon.rs | 4 +- .../tracedecay/src/daemon/bootstrap_route.rs | 61 +------- .../src/daemon/connection_serving.rs | 55 +------ crates/tracedecay/src/daemon/engine.rs | 13 -- crates/tracedecay/src/daemon/projectless.rs | 5 +- .../tracedecay/src/daemon/tests/bootstrap.rs | 14 +- .../tracedecay/src/daemon/tests/handshake.rs | 73 ++-------- crates/tracedecay/src/mcp/server.rs | 5 +- crates/tracedecay/src/mcp/server/requests.rs | 3 - 16 files changed, 104 insertions(+), 421 deletions(-) diff --git a/crates/tracedecay-cli/tests/core_cli_suite/cli_boundary.rs b/crates/tracedecay-cli/tests/core_cli_suite/cli_boundary.rs index ba63bf5024..c080dbe801 100644 --- a/crates/tracedecay-cli/tests/core_cli_suite/cli_boundary.rs +++ b/crates/tracedecay-cli/tests/core_cli_suite/cli_boundary.rs @@ -1,7 +1,7 @@ use std::path::Path; use std::process::Command; -use tracedecay_mcp::get_tool_definitions_with_budget; +use tracedecay_mcp::get_tool_definitions; use crate::common::apply_isolated_profile_env; @@ -30,10 +30,10 @@ fn shipped_binary_stops_quietly_when_a_pipeline_reader_exits() { ); } -/// Help runs without a project graph, so it describes the tool without a -/// node count or call budget it cannot compute. +/// Help and `tools/list` share one static description, so help cannot drift +/// from what hosts see. #[test] -fn context_help_describes_the_tool_without_a_project_size() { +fn context_help_describes_the_tool_with_the_advertised_description() { let home = tempfile::tempdir().expect("isolated home"); let output = sandboxed_command(crate::tracedecay_exe(), home.path()) .args(["tool", "context", "--help"]) @@ -43,16 +43,12 @@ fn context_help_describes_the_tool_without_a_project_size() { assert!(output.status.success(), "{output:?}"); let stdout = String::from_utf8_lossy(&output.stdout); let description = stdout.lines().nth(2).expect("description line"); - let sized = get_tool_definitions_with_budget(6_000, 5) - .expect("budgeted definitions") + let advertised = get_tool_definitions() + .expect("definitions") .into_iter() .find(|definition| definition.name == "tracedecay_context") .expect("context definition") .description; - assert_eq!( - sized, - format!("{description} This project (6000 nodes) allows 5 broad context calls."), - "{stdout}" - ); + assert_eq!(advertised, description, "{stdout}"); assert!(!description.contains("nodes"), "{stdout}"); } diff --git a/crates/tracedecay-mcp-catalog/src/definitions.rs b/crates/tracedecay-mcp-catalog/src/definitions.rs index d254ec1d8e..4dfe3d7102 100644 --- a/crates/tracedecay-mcp-catalog/src/definitions.rs +++ b/crates/tracedecay-mcp-catalog/src/definitions.rs @@ -169,51 +169,14 @@ fn project_selector_object(description: &str) -> Value { }) } -/// Computes the call budget based on project size. -pub fn explore_call_budget(total_nodes: u64) -> u8 { - match total_nodes { - 0..=5_000 => 3, - 5_001..=20_000 => 4, - 20_001..=80_000 => 5, - 80_001..=250_000 => 7, - _ => 10, - } -} - -/// The `tracedecay_context` description for surfaces that have no project -/// graph to size, such as `tracedecay tool context --help`. +/// The static `tracedecay_context` description. Tool descriptions are cached by +/// hosts for a whole session, so they carry no runtime state; live state +/// belongs in each response's `freshness:` and `indexing:` lines. const CONTEXT_DESCRIPTION: &str = "Build an AI-ready context for a task description. Returns \ relevant symbols, relationships, up to three untracked project memory matches when \ available, and optionally code snippets. Use it for broad questions that need \ relationship synthesis across the code graph."; -/// Generates the `tracedecay_context` description with a dynamic call budget. -pub fn context_description(node_count: u64, budget: u8) -> String { - format!( - "{CONTEXT_DESCRIPTION} This project ({node_count} nodes) allows {budget} broad \ - context calls." - ) -} - -/// Returns tool definitions with a dynamic call budget for `tracedecay_context`. -pub fn get_tool_definitions_with_budget( - node_count: u64, - budget: u8, -) -> Result, McpCatalogError> { - let mut defs = get_tool_definitions()?; - apply_context_budget(&mut defs, node_count, budget); - Ok(defs) -} - -fn apply_context_budget(defs: &mut [ToolDefinition], node_count: u64, budget: u8) { - // Replace the context tool's description with the budgeted version - for def in defs { - if def.name == "tracedecay_context" { - def.description = context_description(node_count, budget); - } - } -} - pub fn project_catalog_discovery_scope() -> BTreeSet { [ ScopeDimension::Project, @@ -232,14 +195,6 @@ pub fn project_catalog_discovery_scope() -> BTreeSet { .collect() } -/// The `tracedecay_context` description while the project graph is still warming. -pub fn context_warming_description(budget: u8) -> String { - format!( - "{CONTEXT_DESCRIPTION} The graph is still warming, and {budget} broad context calls \ - are available." - ) -} - /// Returns the list of all tool definitions exposed by this MCP server. pub fn get_tool_definitions() -> Result, McpCatalogError> { Ok(get_tool_definitions_ref()?.to_vec()) @@ -293,11 +248,9 @@ fn build_search_cli_definition() -> Result { /// Borrow the registry, assembled once per process. /// /// Every input is static for the life of the process: the application catalog -/// is a `LazyLock` snapshot. Nothing session-scoped is frozen here, the -/// per-session passes (the context description budget and the -/// profile/capability filtering in -/// `get_catalog_filtered_tool_definitions_with_budget`) all run on a clone, -/// after the cache. +/// is a `LazyLock` snapshot. Descriptions carry no runtime state, and the +/// per-session profile/capability filtering in +/// `get_catalog_filtered_tool_definitions` runs on a clone, after the cache. pub fn get_tool_definitions_ref() -> Result<&'static [ToolDefinition], McpCatalogError> { // The error type is not `Clone`, and a failure here is a deterministic // catalog/schema defect rather than a transient condition, so the cache diff --git a/crates/tracedecay-mcp-catalog/src/definitions/tests.rs b/crates/tracedecay-mcp-catalog/src/definitions/tests.rs index ded3f5da17..192b3ec031 100644 --- a/crates/tracedecay-mcp-catalog/src/definitions/tests.rs +++ b/crates/tracedecay-mcp-catalog/src/definitions/tests.rs @@ -292,52 +292,22 @@ fn search_cli_definition_matches_the_advertised_contract() { ); } -/// Caching the registry must not freeze anything session-scoped into it. -/// -/// The per-session passes mutate the vector they are handed, so every caller -/// has to receive an independent clone. If the cache handed out shared state, -/// one session's context budget would be visible to the next. +/// Hosts cache `tools/list` for a session, so no description may embed state +/// that changes while it runs; that state belongs in response headers. #[test] -fn per_session_budget_does_not_leak_through_the_cached_registry() { - fn context_description(definitions: &[ToolDefinition]) -> String { - definitions - .iter() - .find(|definition| definition.name == "tracedecay_context") - .map(|definition| definition.description.clone()) - .expect("tracedecay_context is advertised") +fn context_description_carries_no_runtime_state() { + let definitions = get_tool_definitions().expect("tool definitions"); + let description = &definitions + .iter() + .find(|definition| definition.name == "tracedecay_context") + .expect("tracedecay_context is advertised") + .description; + for stale in ["warming", "broad context calls", "nodes"] { + assert!( + !description.contains(stale), + "context description must be static, found {stale:?}: {description}" + ); } - - let small = get_tool_definitions_with_budget(11, 2).expect("tool definitions"); - let small_description = context_description(&small); - assert!( - small_description.contains("2 broad context calls"), - "budget must reach the context description: {small_description}" - ); - - let large = get_tool_definitions_with_budget(999_999, 9).expect("tool definitions"); - let large_description = context_description(&large); - assert!( - large_description.contains("9 broad context calls"), - "budget must reach the context description: {large_description}" - ); - - assert_ne!( - small_description, large_description, - "two sessions with different budgets must not share one description" - ); - assert_eq!( - context_description(&small), - small_description, - "the earlier session's definitions must not be rewritten by a later one" - ); - - // A third, unbudgeted read must still see the neutral registry. - let neutral = get_tool_definitions().expect("tool definitions"); - let neutral_description = context_description(&neutral); - assert!( - !neutral_description.contains("9 broad context calls"), - "an unbudgeted caller inherited another session's budget: {neutral_description}" - ); } #[test] diff --git a/crates/tracedecay-mcp-catalog/src/lib.rs b/crates/tracedecay-mcp-catalog/src/lib.rs index 18bab28023..f58f8f379f 100644 --- a/crates/tracedecay-mcp-catalog/src/lib.rs +++ b/crates/tracedecay-mcp-catalog/src/lib.rs @@ -37,11 +37,9 @@ mod project_access; pub use catalog_error::McpCatalogError; pub use category::ToolCategory; pub use definitions::{ - ALWAYS_LOAD_META, RESPONSE_RETRIEVE_TOOL, cli_tool_definition, context_description, - context_warming_description, explore_call_budget, format_capable_tool_names, - get_tool_definitions, get_tool_definitions_ref, get_tool_definitions_with_budget, - mcp_input_schema, project_catalog_discovery_scope, tool_defaults_to_markdown, work_tool_name, - workflow_tool_name, + ALWAYS_LOAD_META, RESPONSE_RETRIEVE_TOOL, cli_tool_definition, format_capable_tool_names, + get_tool_definitions, get_tool_definitions_ref, mcp_input_schema, + project_catalog_discovery_scope, tool_defaults_to_markdown, work_tool_name, workflow_tool_name, }; pub use project_access::registered_project_reader_tool_names; diff --git a/crates/tracedecay-mcp/src/lib.rs b/crates/tracedecay-mcp/src/lib.rs index 7c47301e84..acf20ba313 100644 --- a/crates/tracedecay-mcp/src/lib.rs +++ b/crates/tracedecay-mcp/src/lib.rs @@ -99,10 +99,9 @@ pub use tools::{ }; pub use tracedecay_mcp_catalog::{ ALWAYS_LOAD_META, MAX_RESPONSE_CHARS, McpCatalogError, ToolCategory, ToolDefinition, - cli_tool_definition, context_description, context_warming_description, explore_call_budget, - format_capable_tool_names, get_tool_definitions, get_tool_definitions_ref, - get_tool_definitions_with_budget, mcp_input_schema, project_catalog_discovery_scope, - registered_project_reader_tool_names, tool_defaults_to_markdown, + cli_tool_definition, format_capable_tool_names, get_tool_definitions, get_tool_definitions_ref, + mcp_input_schema, project_catalog_discovery_scope, registered_project_reader_tool_names, + tool_defaults_to_markdown, }; pub use workflow::{ LibtestReport, MAX_TEST_TIMEOUT_SECS, RunAffectedArgs, TestProfile, TestRunControl, diff --git a/crates/tracedecay-mcp/src/tools/binding.rs b/crates/tracedecay-mcp/src/tools/binding.rs index 4916337c77..7ea4a03bcd 100644 --- a/crates/tracedecay-mcp/src/tools/binding.rs +++ b/crates/tracedecay-mcp/src/tools/binding.rs @@ -1295,16 +1295,14 @@ mod tests { ]; fn advertised_tool_names() -> Vec { + use crate::project_catalog_discovery_scope; use crate::tools::catalog_discovery::{ - default_catalog_discovery_authority, get_catalog_filtered_tool_definitions_with_budget, + default_catalog_discovery_authority, get_catalog_filtered_tool_definitions, }; - use crate::{explore_call_budget, project_catalog_discovery_scope}; let profile_id = ProfileId::new(tracedecay_contracts::APPLICATION_DEFAULT_PROFILE_ID) .expect("default profile"); - get_catalog_filtered_tool_definitions_with_budget( - 0, - explore_call_budget(0), + get_catalog_filtered_tool_definitions( &profile_id, &default_catalog_discovery_authority().expect("default discovery authority"), &project_catalog_discovery_scope(), diff --git a/crates/tracedecay-mcp/src/tools/catalog_discovery.rs b/crates/tracedecay-mcp/src/tools/catalog_discovery.rs index dc4b7ca2bd..aac0237dfc 100644 --- a/crates/tracedecay-mcp/src/tools/catalog_discovery.rs +++ b/crates/tracedecay-mcp/src/tools/catalog_discovery.rs @@ -4,9 +4,7 @@ use std::collections::{BTreeSet, HashMap}; use std::sync::{Arc, LazyLock, RwLock}; use crate::handlers::multi_root_tool_name; -use crate::{ - ToolDefinition, context_description, context_warming_description, get_tool_definitions, -}; +use crate::{ToolDefinition, get_tool_definitions}; use serde_json::Value; use sha2::{Digest, Sha256}; use tracedecay_api::{WorkOperation, WorkflowOperation}; @@ -26,8 +24,8 @@ use super::dispatch::McpDispatchMetadataError; /// /// The live key space is profile × capability-set digest × scope digest. /// Production callers share one default profile and one project scope; tests -/// add a handful of capability-set variants. Budget and node count are patched -/// onto a hit and are not keys. +/// add a handful of capability-set variants. Descriptions remain static across +/// runtime state changes. const DISCOVERY_CACHE_MAX_ENTRIES: usize = 32; #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] @@ -93,8 +91,8 @@ fn discovery_cache_key( } } -/// Node-independent compose: tool definitions, catalog filter, and -/// dispatch-contract metadata. Context descriptions are patched on serve. +/// Compose static tool definitions, the catalog filter, and dispatch-contract +/// metadata for the admitted capability and scope authority. fn compose_node_independent_definitions( profile_id: &ProfileId, authorized_capabilities: &BTreeSet, @@ -215,56 +213,16 @@ fn discovery_cache_get_or_insert( Ok(entry) } -fn context_description_for(node_count: Option, budget: u8) -> String { - match node_count { - None => context_warming_description(budget), - Some(node_count) => context_description(node_count, budget), - } -} - -fn patch_context_description_in_payload( - payload: &mut Value, - description: String, -) -> Result<(), McpDispatchMetadataError> { - let tools = payload - .get_mut("tools") - .and_then(Value::as_array_mut) - .ok_or_else(|| { - McpDispatchMetadataError::Initialization( - "cached tools/list payload is missing the tools array".to_owned(), - ) - })?; - for tool in tools { - if tool.get("name").and_then(Value::as_str) == Some("tracedecay_context") { - let object = tool.as_object_mut().ok_or_else(|| { - McpDispatchMetadataError::Initialization( - "cached tracedecay_context entry is not an object".to_owned(), - ) - })?; - object.insert("description".to_owned(), Value::String(description)); - return Ok(()); - } - } - Ok(()) -} - /// Decodes the live `tools/list` discovery payload into tool definitions for /// assertions. #[cfg(test)] -pub(crate) fn get_catalog_filtered_tool_definitions_with_budget( - node_count: u64, - budget: u8, +pub(crate) fn get_catalog_filtered_tool_definitions( profile_id: &ProfileId, authorized_capabilities: &BTreeSet, available_scope: &BTreeSet, ) -> Result, McpDispatchMetadataError> { - let mut payload = catalog_discovery_tools_list_payload( - Some(node_count), - budget, - profile_id, - authorized_capabilities, - available_scope, - )?; + let mut payload = + catalog_discovery_tools_list_payload(profile_id, authorized_capabilities, available_scope)?; let tools = payload.get_mut("tools").map(Value::take).ok_or_else(|| { McpDispatchMetadataError::Initialization( "cached tools/list payload is missing the tools array".to_owned(), @@ -279,24 +237,18 @@ pub(crate) fn get_catalog_filtered_tool_definitions_with_budget( /// Composed `{"tools": [...]}` discovery payload for `tools/list`. /// -/// A hit clones the cached `Value` once and patches only the dynamic -/// `tracedecay_context` description. It does not deep-clone definitions or -/// re-serialize dispatch contracts. +/// Descriptions are static: hosts cache the list for a session, so live state +/// such as warming is reported per response, never here. A hit clones the +/// cached `Value` once and does not deep-clone definitions or re-serialize +/// dispatch contracts. pub fn catalog_discovery_tools_list_payload( - node_count: Option, - budget: u8, profile_id: &ProfileId, authorized_capabilities: &BTreeSet, available_scope: &BTreeSet, ) -> Result { let entry = discovery_cache_get_or_insert(profile_id, authorized_capabilities, available_scope)?; - let mut payload = (*entry).clone(); - patch_context_description_in_payload( - &mut payload, - context_description_for(node_count, budget), - )?; - Ok(payload) + Ok((*entry).clone()) } pub fn default_catalog_discovery_authority() @@ -312,15 +264,13 @@ pub fn default_catalog_discovery_authority() #[cfg(test)] mod tests { use super::*; - use crate::{explore_call_budget, project_catalog_discovery_scope}; + use crate::project_catalog_discovery_scope; #[test] fn catalog_filtered_discovery_advertises_dispatch_contracts() { let profile_id = ProfileId::new(tracedecay_contracts::APPLICATION_DEFAULT_PROFILE_ID) .expect("default profile"); - let definitions = get_catalog_filtered_tool_definitions_with_budget( - 0, - explore_call_budget(0), + let definitions = get_catalog_filtered_tool_definitions( &profile_id, &default_catalog_discovery_authority().expect("default discovery authority"), &project_catalog_discovery_scope(), @@ -428,9 +378,7 @@ mod tests { #[test] fn catalog_filter_preserves_non_catalog_tools_and_filters_catalog_bindings() { let profile = ProfileId::new(tracedecay_contracts::APPLICATION_DEFAULT_PROFILE_ID).unwrap(); - let definitions = get_catalog_filtered_tool_definitions_with_budget( - 10_000, - 4, + let definitions = get_catalog_filtered_tool_definitions( &profile, &BTreeSet::new(), &project_catalog_discovery_scope(), @@ -548,19 +496,17 @@ mod tests { } #[test] - fn discovery_advertises_rewrite_and_the_requested_context_budget() { + fn discovery_advertises_rewrite_with_a_state_free_context_description() { let (profile, authority, scope) = default_discovery_inputs(); - let payload = - catalog_discovery_tools_list_payload(Some(6_000), 4, &profile, &authority, &scope) - .expect("discovery payload"); + let payload = catalog_discovery_tools_list_payload(&profile, &authority, &scope) + .expect("discovery payload"); assert_rewrite_is_advertised(&payload); + let description = advertised_tool(&payload, "tracedecay_context")["description"] + .as_str() + .expect("context description"); assert!( - advertised_tool(&payload, "tracedecay_context")["description"] - .as_str() - .expect("context description") - .contains("This project (6000 nodes) allows 4 broad context calls."), - "{}", - advertised_tool(&payload, "tracedecay_context")["description"] + !description.contains("warming") && !description.contains("broad context calls"), + "{description}" ); } @@ -569,17 +515,10 @@ mod tests { with_isolated_discovery_cache(|| { let (profile, full_authority, scope) = default_discovery_inputs(); let empty_authority = BTreeSet::new(); - let full = - catalog_discovery_tools_list_payload(Some(0), 3, &profile, &full_authority, &scope) - .expect("full-authority payload"); - let empty = catalog_discovery_tools_list_payload( - Some(0), - 3, - &profile, - &empty_authority, - &scope, - ) - .expect("empty-authority payload"); + let full = catalog_discovery_tools_list_payload(&profile, &full_authority, &scope) + .expect("full-authority payload"); + let empty = catalog_discovery_tools_list_payload(&profile, &empty_authority, &scope) + .expect("empty-authority payload"); assert_rewrite_is_advertised(&full); assert!(advertises(&full, "tracedecay_search")); assert!(advertises(&full, "tracedecay_configuration_get")); @@ -587,16 +526,11 @@ mod tests { assert!(advertises(&empty, "tracedecay_multi_root_execute")); let full_again = - catalog_discovery_tools_list_payload(Some(0), 3, &profile, &full_authority, &scope) + catalog_discovery_tools_list_payload(&profile, &full_authority, &scope) .expect("full-authority cache hit"); - let empty_again = catalog_discovery_tools_list_payload( - Some(0), - 3, - &profile, - &empty_authority, - &scope, - ) - .expect("empty-authority cache hit"); + let empty_again = + catalog_discovery_tools_list_payload(&profile, &empty_authority, &scope) + .expect("empty-authority cache hit"); assert_rewrite_is_advertised(&full_again); assert!(advertises(&full_again, "tracedecay_search")); assert!(!advertises(&empty_again, "tracedecay_search")); @@ -605,8 +539,6 @@ mod tests { let mut without_configuration = scope.clone(); without_configuration.remove(&ScopeDimension::ConfigurationLayer); let scoped = catalog_discovery_tools_list_payload( - Some(0), - 3, &profile, &full_authority, &without_configuration, @@ -615,8 +547,6 @@ mod tests { assert_rewrite_is_advertised(&scoped); assert!(!advertises(&scoped, "tracedecay_configuration_get")); let scoped_again = catalog_discovery_tools_list_payload( - Some(0), - 3, &profile, &full_authority, &without_configuration, diff --git a/crates/tracedecay/src/daemon.rs b/crates/tracedecay/src/daemon.rs index cb9168216e..ee347bf5f8 100644 --- a/crates/tracedecay/src/daemon.rs +++ b/crates/tracedecay/src/daemon.rs @@ -42,6 +42,7 @@ pub(crate) use tracedecay_daemon_protocol::{ }; pub(crate) use tracedecay_daemon_protocol::{DaemonClientIdentity, DaemonHandshake}; use tracedecay_domain::errors::{ProjectOpenFailureKind, Result, TraceDecayError}; +use tracedecay_mcp::project_catalog_discovery_scope; use tracedecay_mcp::tools::catalog_discovery::{ catalog_discovery_tools_list_payload, default_catalog_discovery_authority, }; @@ -49,7 +50,6 @@ use tracedecay_mcp::transport::ReplayTransport; use tracedecay_mcp::{ BrokerStreamTransport, ErrorCode, JsonRpcError, JsonRpcRequest, JsonRpcResponse, McpTransport, }; -use tracedecay_mcp::{explore_call_budget, project_catalog_discovery_scope}; use tracedecay_runtime_core::cancellation::CancellationToken; /// Human-facing detail fragment for a still-warming project/profile owner. @@ -301,7 +301,7 @@ mod bootstrap; mod bootstrap_route; use bootstrap_route::{ apply_daemon_initialize_route, attach_initialize_route_metadata, attach_reset_required_stores, - cached_project_node_count, daemon_bootstrap_response, prewarm_daemon_bootstrap_catalog, + daemon_bootstrap_response, prewarm_daemon_bootstrap_catalog, }; mod branch_add; mod branch_admin; diff --git a/crates/tracedecay/src/daemon/bootstrap_route.rs b/crates/tracedecay/src/daemon/bootstrap_route.rs index 4549bf7ca9..f2ae78f40a 100644 --- a/crates/tracedecay/src/daemon/bootstrap_route.rs +++ b/crates/tracedecay/src/daemon/bootstrap_route.rs @@ -9,7 +9,7 @@ use tracedecay_mcp::server::{ request_protocol_version, speaks_2026_07_28, stamp_2026_07_28_result, }; -fn bootstrap_tools_list_payload(node_count: Option, budget: u8) -> Result { +fn bootstrap_tools_list_payload() -> Result { let profile_id = tracedecay_tool_catalog::ProfileId::new( tracedecay_contracts::APPLICATION_DEFAULT_PROFILE_ID, ) @@ -21,8 +21,6 @@ fn bootstrap_tools_list_payload(node_count: Option, budget: u8) -> Result, budget: u8) -> Result Result { - bootstrap_tools_list_payload(None, explore_call_budget(0)) -} - +#[tracing::instrument(name = "daemon.bootstrap.prewarm_catalog", level = "trace", skip_all)] pub(super) fn prewarm_daemon_bootstrap_catalog() -> Result<()> { - warming_bootstrap_tools_list_payload().map(|_| ()) + bootstrap_tools_list_payload().map(|_| ()) } #[tracing::instrument(name = "daemon.bootstrap.initialize_route", level = "trace", skip_all)] @@ -138,7 +132,6 @@ pub(super) async fn attach_reset_required_stores( pub(super) fn daemon_bootstrap_response( request: &JsonRpcRequest, route: Option<&InitializeRouteMetadata>, - project_node_count: Option, ) -> Option> { match classify_mcp_method(&request.method) { McpMethod::Initialize => Some(request.id.clone().map(|id| { @@ -166,11 +159,9 @@ pub(super) fn daemon_bootstrap_response( .map(|id| JsonRpcResponse::success(id, json!({}))), ), McpMethod::ToolsList => Some(request.id.clone().map(|id| { - let budget = - project_node_count.map_or_else(|| explore_call_budget(0), explore_call_budget); let payload = { let _span = tracing::trace_span!("daemon.bootstrap.catalog").entered(); - bootstrap_tools_list_payload(project_node_count, budget) + bootstrap_tools_list_payload() }; match payload { Ok(mut payload) => { @@ -190,47 +181,3 @@ pub(super) fn daemon_bootstrap_response( _ => None, } } - -#[tracing::instrument( - name = "daemon.bootstrap.project_node_count", - level = "trace", - skip_all -)] -pub(super) async fn cached_project_node_count( - store_administration: &StoreAdministration, - handshake: &DaemonHandshake, -) -> Option { - cached_project_node_count_inner(store_administration, handshake).await -} - -fn cached_project_node_count_inner<'a>( - store_administration: &'a StoreAdministration, - handshake: &'a DaemonHandshake, -) -> std::pin::Pin> + Send + 'a>> { - // Erase the deeply nested future before it reaches the measured wrapper - // so every profiling feature can compute its layout. - Box::pin(async move { - let project_path = handshake.project_path.as_ref()?; - let canonical_project_path = - tracedecay_runtime_core::path_safety::canonical_root_identity(project_path); - let route = ProjectRouteKey::from_handshake(&canonical_project_path, handshake).ok()?; - let _server = { - let servers = store_administration.project_servers().lock().await; - servers - .get_route(&route) - .map(|(_, server)| Arc::clone(server)) - }?; - ensure_registered_project_route( - store_administration, - &canonical_project_path, - handshake.allow_init, - ) - .await - .ok()?; - // Bootstrap routing does not receive the daemon invocation state's - // retained code-index scheduler. A mounted project alone cannot prove a - // current generation or node count, so catalog discovery stays in its - // explicit warming state instead of reading the retired SQLite graph. - None - }) -} diff --git a/crates/tracedecay/src/daemon/connection_serving.rs b/crates/tracedecay/src/daemon/connection_serving.rs index 661c040b54..872235f48b 100644 --- a/crates/tracedecay/src/daemon/connection_serving.rs +++ b/crates/tracedecay/src/daemon/connection_serving.rs @@ -1398,27 +1398,9 @@ fn serve_broker_socket_client_inner( } else { (false, None) }; - let project_node_count = - if matches!(classify_mcp_method(&request.method), McpMethod::ToolsList) - { - if handshake.project_path.is_some() { - cached_project_node_count( - &engine.store_administration, - &handshake, - ) - .await - } else { - Some(0) - } - } else { - None - }; if !initialized_project_server_ready - && let Some(mut response) = daemon_bootstrap_response( - request, - initialize_route.as_ref(), - project_node_count, - ) + && let Some(mut response) = + daemon_bootstrap_response(request, initialize_route.as_ref()) { let project_open_error = match admission_refusal { Some(refusal) => initialize_project_open_error(refusal), @@ -1467,25 +1449,8 @@ fn serve_broker_socket_client_inner( )) .await; } - // Keep catalog-refresh bookkeeping consistent with the regular MCP - // server path. Only a warming `tools/list` (no published node count) - // or an initialize answered while a project graph is still opening - // is provisional. `project_node_count` is computed only for - // `tools/list`, so treating every `None` as provisional also - // skipped projectless initialize (must mark current) and - // `notifications/initialized` (must emit a pending refresh). - let catalog_is_provisional = match classify_mcp_method(&request.method) - { - McpMethod::ToolsList => project_node_count.is_none(), - McpMethod::Initialize => handshake.project_path.is_some(), - _ => false, - }; if let Some(key) = engine - .claim_catalog_refresh( - &handshake, - first_request.parsed(), - catalog_is_provisional, - ) + .claim_catalog_refresh(&handshake, first_request.parsed()) .await && let Err(error) = write_tool_list_changed_notification(&mut transport).await @@ -1584,7 +1549,7 @@ fn serve_broker_socket_client_inner( // The stdio proxy creates one daemon connection per request. The request // was peeked above so initialize-root routing happens before project open. if let Some(key) = engine - .claim_catalog_refresh(&handshake, first_request.parsed(), false) + .claim_catalog_refresh(&handshake, first_request.parsed()) .await && let Err(error) = write_tool_list_changed_notification(&mut transport).await { @@ -1986,19 +1951,9 @@ pub(super) async fn serve_windows_broker_client_with_class_and_invocation( } else { (false, None) }; - let project_node_count = - if matches!(classify_mcp_method(&request.method), McpMethod::ToolsList) { - if handshake.project_path.is_some() { - cached_project_node_count(&store_administration, &handshake).await - } else { - Some(0) - } - } else { - None - }; if !initialized_project_server_ready && let Some(mut response) = - daemon_bootstrap_response(request, initialize_route.as_ref(), project_node_count) + daemon_bootstrap_response(request, initialize_route.as_ref()) { let project_open_error = match admission_refusal { Some(refusal) => initialize_project_open_error(refusal), diff --git a/crates/tracedecay/src/daemon/engine.rs b/crates/tracedecay/src/daemon/engine.rs index 213d5319ac..4abebffb8c 100644 --- a/crates/tracedecay/src/daemon/engine.rs +++ b/crates/tracedecay/src/daemon/engine.rs @@ -297,15 +297,6 @@ impl DaemonEngine { /// capability are eligible. `initialize` and `tools/list` mark the client /// current without emitting because those requests already fetch the new /// generation's catalog. - /// - /// `catalog_is_provisional` marks a discovery answer served from the - /// warming bootstrap route, before the project graph is open. That catalog - /// is not the published one, its `tracedecay_context` budget is the - /// conservative warming budget rather than the node-count budget, so it - /// must not mark the client current. Leaving such a client unmarked is - /// exactly what arms its notification for the first request after warm-up - /// completes; marking it would strand the provisional catalog for the rest - /// of the daemon's life, because this set is never otherwise cleared. #[tracing::instrument( name = "daemon.engine.claim_catalog_refresh", level = "trace", @@ -315,7 +306,6 @@ impl DaemonEngine { &self, handshake: &DaemonHandshake, request: Option<&JsonRpcRequest>, - catalog_is_provisional: bool, ) -> Option { if !valid_client_instance_id(&handshake.client_instance_id) { return None; @@ -324,9 +314,6 @@ impl DaemonEngine { if request.method == HOOK_EVENT_METHOD { return None; } - if catalog_is_provisional { - return None; - } let catalog_is_current = matches!(request.method.as_str(), "initialize" | "tools/list"); if !catalog_is_current && (!handshake.tool_list_changed_capable || handshake.catalog_version.is_empty()) diff --git a/crates/tracedecay/src/daemon/projectless.rs b/crates/tracedecay/src/daemon/projectless.rs index 86b8c79dc1..1084a0579f 100644 --- a/crates/tracedecay/src/daemon/projectless.rs +++ b/crates/tracedecay/src/daemon/projectless.rs @@ -13,8 +13,7 @@ use tracedecay_mcp::tools::catalog_discovery::{ catalog_discovery_tools_list_payload, default_catalog_discovery_authority, }; use tracedecay_mcp::{ - ErrorCode, JsonRpcRequest, JsonRpcResponse, McpTransport, explore_call_budget, - project_catalog_discovery_scope, + ErrorCode, JsonRpcRequest, JsonRpcResponse, McpTransport, project_catalog_discovery_scope, }; use tracedecay_tool_catalog::ApplicationSurfaceOperation; @@ -249,8 +248,6 @@ fn projectless_tools_list_payload() -> std::result::Result JsonRpcResponse { - let budget = explore_call_budget(0); let profile_id = match tracedecay_tool_catalog::ProfileId::new( tracedecay_contracts::APPLICATION_DEFAULT_PROFILE_ID, ) { @@ -698,8 +697,6 @@ impl McpServer { let match_result = { let _span = tracing::trace_span!("mcp.server.tools_list.compose").entered(); tracedecay_mcp::tools::catalog_discovery::catalog_discovery_tools_list_payload( - None, - budget, &profile_id, &authority, &project_catalog_discovery_scope(), From 866fcc108f652defddd777e91e9da1c3c6d5f270 Mon Sep 17 00:00:00 2001 From: Zack Jackson <25274700+ScriptedAlchemy@users.noreply.github.com> Date: Mon, 26 Oct 2026 16:33:43 -0700 Subject: [PATCH 8/8] test(daemon): backport deterministic crash recovery checks Carry the reader-lease publication barrier and scheduled maintenance observation from the repaired parent PRs. Keep the release branch update limited to the crash-recovery fixture. --- .../sealed_generation_crash_test.rs | 107 +++++++++++++++--- 1 file changed, 90 insertions(+), 17 deletions(-) diff --git a/crates/tracedecay/tests/daemon_suite/sealed_generation_crash_test.rs b/crates/tracedecay/tests/daemon_suite/sealed_generation_crash_test.rs index 60b6302b7b..be15308ded 100644 --- a/crates/tracedecay/tests/daemon_suite/sealed_generation_crash_test.rs +++ b/crates/tracedecay/tests/daemon_suite/sealed_generation_crash_test.rs @@ -4,20 +4,24 @@ //! temporary name, flushed once, and only then named; the manifest and the //! active pointer follow. A kill after the pointer is durable must restart on //! the exact sealed bytes. A kill before it must leave the prior generation -//! published and no partial generation or temporary behind once the restarted -//! daemon rebuilds. +//! published, then rebuild and collect the abandoned publication through the +//! restarted daemon's scheduled maintenance. use std::collections::BTreeMap; use std::fmt::Write as _; use std::fs; use std::path::{Path, PathBuf}; -use std::time::Instant; +use std::time::{Duration, Instant}; use serde_json::json; use sha2::{Digest, Sha256}; use tracedecay_code_index_retention::code_index_generations::{ + CODE_INDEX_PREPARATION_DIRECTORY_PREFIX_V1, CodeGenerationStoreLockV1, code_generation_segments_root, code_text_artifacts_root, scoped_code_index_store_root, + try_acquire_code_generation_store_read_lock, }; +use tracedecay_configuration::RetentionConfig; +use tracedecay_maintenance::tick::MaintenanceCadence; use crate::code_index_journey::{ RECEIPT_TIMEOUT, commit_all, exact_identity, git, initialize_tracedecay, @@ -26,8 +30,11 @@ use crate::code_index_journey::{ use crate::common::{IsolatedHome, daemon_socket_path, spawn_tracedecay_daemon_with}; use tracedecay_runtime_core::path_safety::canonical_existing_identity; -const PUBLICATION_TEMPORARY_PREFIXES: [&str; 2] = - [".segment-publication.", ".evidence-pack-publication."]; +const PUBLICATION_TEMPORARY_PREFIXES: [&str; 3] = [ + ".segment-publication.", + ".evidence-pack-publication.", + CODE_INDEX_PREPARATION_DIRECTORY_PREFIX_V1, +]; fn scope_root(home: &Path, project: &Path) -> PathBuf { let layout = @@ -89,10 +96,47 @@ fn publication_temporaries(scope: &Path) -> Vec { .collect() } -fn segments_entry_count(scope: &Path) -> usize { - fs::read_dir(code_generation_segments_root(scope)) - .expect("segments directory") - .count() +fn hold_publication_commit(scope: &Path) -> CodeGenerationStoreLockV1 { + let deadline = Instant::now() + RECEIPT_TIMEOUT; + loop { + if let Some(lease) = try_acquire_code_generation_store_read_lock(scope) + .expect("read lease on the published generation") + { + return lease; + } + assert!( + Instant::now() < deadline, + "the published generation stayed busy" + ); + std::thread::sleep(std::time::Duration::from_millis(1)); + } +} + +fn has_staged_file_segment(scope: &Path) -> bool { + for entry in fs::read_dir(code_generation_segments_root(scope)).expect("segments directory") { + let entry = entry.expect("segments entry"); + if !entry + .file_name() + .to_string_lossy() + .starts_with(CODE_INDEX_PREPARATION_DIRECTORY_PREFIX_V1) + { + continue; + } + let staged = match fs::read_dir(entry.path()) { + Ok(staged) => staged, + // A source update can retire an earlier preparation before its + // successor starts. Observe the successor on the next probe. + Err(error) if error.kind() == std::io::ErrorKind::NotFound => continue, + Err(error) => panic!("read generation preparation: {error}"), + }; + if staged + .map(|entry| entry.expect("staged segment entry")) + .any(|entry| entry.file_name().to_string_lossy().starts_with("segment-")) + { + return true; + } + } + false } fn write_batch(project: &Path, files: u32, symbols: u32) { @@ -229,11 +273,17 @@ async fn sigkill_during_the_seal_keeps_the_prior_generation_published() { ) .await; let scope = scope_root(environment.home(), &project); + // The real reader lease permits segment preparation but excludes the + // final publication transaction. Keep it through SIGKILL so even a fast + // writer cannot advance the pointer between observation and the kill. + let publication_hold = hold_publication_commit(&scope); let prior_pointer = active_pointer(&scope); let prior_family = sealed_family(&scope); - let prior_entries = segments_entry_count(&scope); - write_batch(&project, 128, 16); + // The reader lease fixes the kill point; a large batch is unnecessary + // and can spread abandoned-file collection across several maintenance + // ticks. Keep this multi-file publication within one bounded sweep. + write_batch(&project, 16, 16); let batch_revision = commit_all(&project, "install the batch the killed seal was writing"); let receipt = tool( &socket, @@ -243,10 +293,10 @@ async fn sigkill_during_the_seal_keeps_the_prior_generation_published() { ) .await; assert_eq!(receipt["status"], "queued", "refresh receipt: {receipt}"); - // The seal's first segment write is the first new entry beside the prior - // generation's segments; kill the daemon while that seal is in flight. + // Segments now accumulate inside one preparation directory. Top-level + // entry counts only advance when commit names the complete batch. let deadline = Instant::now() + RECEIPT_TIMEOUT; - while segments_entry_count(&scope) < prior_entries + 2 { + while !has_staged_file_segment(&scope) { assert!( Instant::now() < deadline, "the refresh never started sealing its segments" @@ -254,6 +304,7 @@ async fn sigkill_during_the_seal_keeps_the_prior_generation_published() { std::thread::sleep(std::time::Duration::from_millis(1)); } let killed = daemon.kill_and_wait().expect("SIGKILL the sealing daemon"); + drop(publication_hold); assert!( !killed.success(), "SIGKILL must not look like a graceful exit" @@ -271,6 +322,11 @@ async fn sigkill_during_the_seal_keeps_the_prior_generation_published() { "the kill damaged the prior generation's durable file {path}" ); } + let abandoned_temporaries = publication_temporaries(&scope); + assert!( + !abandoned_temporaries.is_empty(), + "the interrupted seal must leave publication work for recovery" + ); daemon = spawn_tracedecay_daemon_with(environment.home(), |_| {}); let rebuilt = wait_for_terminal_generation( @@ -281,13 +337,30 @@ async fn sigkill_during_the_seal_keeps_the_prior_generation_published() { "refs/heads/main", Some(&batch_revision), Some(&prior.generation_id), - "crash_probe_0127_015", - Some("src/batch/file_0127.rs"), + "crash_probe_0015_015", + Some("src/batch/file_0015.rs"), ) .await; assert_ne!(rebuilt.generation_id, prior.generation_id); + // Rebuilding does not run retention: its next admitted tick is one retry + // delay away (a minute under the default policy). Start the unchanged + // completion budget after that scheduled delay. Observe only the killed + // seal's names, since a live successor may legitimately prepare work. + let cadence = MaintenanceCadence::new(Duration::from_hours( + RetentionConfig::default().interval_hours.max(1), + )); + let deadline = Instant::now() + cadence.retry_delay() + RECEIPT_TIMEOUT; + let pending_temporaries = || { + publication_temporaries(&scope) + .into_iter() + .filter(|name| abandoned_temporaries.contains(name)) + .collect::>() + }; + while !pending_temporaries().is_empty() && Instant::now() < deadline { + std::thread::sleep(std::time::Duration::from_millis(10)); + } assert_eq!( - publication_temporaries(&scope), + pending_temporaries(), Vec::::new(), "the restarted daemon must collect the killed seal's temporaries" );