mirror of
https://github.com/Dicklesworthstone/coding_agent_session_search.git
synced 2026-09-22 11:59:25 +08:00
8619fa7a21
Discover Codex's archived_sessions alongside active sessions from default, CODEX_HOME, full-home and mirrored roots. Keep narrow session/file scopes narrow and use the same inventory for discovery and guarded recovery. Archive moves preserve mtime, so inventory archives independently of the active cutoff and leave unchanged-source reuse to the existing host hook. Preserve full-home native dated IDs across archive/unarchive moves while retaining explicitly scoped archive identities and original provenance. Separate the public source-selection surface from the byte-identical existing parsing/enrichment implementation. Add real-consumer regressions for both collections, old archived files, archive-only homes, exclusions, root scopes, remote provenance, identity stability and failed archives. Use existing published dependencies; no pin or lockfile change. Also correct the import ordering left by the prior resume-test commit.
153 lines
7.1 KiB
Python
Executable File
153 lines
7.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Run the real CASS Codex module and its tests without the storage/TUI build.
|
|
|
|
python3 scripts/test_codex_contract.py
|
|
python3 scripts/test_codex_contract.py --fad-checkout ../franken_agent_detection
|
|
|
|
The temporary crate stages byte-identical production Rust files with their
|
|
normal module layout; there is no maintained fork or mock connector.
|
|
By default dependency versions and the initial lockfile come from CASS.
|
|
--fad-checkout tests an upstream change before publication, verifies Cargo
|
|
selected that checkout, and changes only the temporary crate's dependency.
|
|
Only FAD's unrelated SQLite/crypto features are omitted. The integration
|
|
tests also remain normal CASS cargo test targets.
|
|
Requires Python 3.11+ and the repository's Rust toolchain.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import shutil
|
|
import subprocess
|
|
import tempfile
|
|
import tomllib
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("--fad-checkout", type=Path, help="Test this local FAD checkout without changing CASS's published dependency pin")
|
|
args = parser.parse_args()
|
|
fad_checkout = None
|
|
fad_version = ""
|
|
if args.fad_checkout is not None:
|
|
try:
|
|
fad_checkout = args.fad_checkout.resolve(strict=True)
|
|
package = tomllib.loads((fad_checkout / "Cargo.toml").read_text(encoding="utf-8"))["package"]
|
|
if package.get("name") != "franken-agent-detection" or not isinstance(package.get("version"), str):
|
|
raise ValueError("expected the franken-agent-detection package with an explicit version")
|
|
fad_version = package["version"]
|
|
except (OSError, KeyError, ValueError) as error:
|
|
parser.error(f"invalid --fad-checkout: {error}")
|
|
|
|
root = Path(__file__).resolve().parents[1]
|
|
manifest = tomllib.loads((root / "Cargo.toml").read_text(encoding="utf-8"))
|
|
dependencies = manifest["dependencies"]
|
|
names = (
|
|
"anyhow", "blake3", "chrono", "dirs", "dotenvy", "franken-agent-detection",
|
|
"serde", "serde_json", "tempfile", "thiserror", "tracing",
|
|
)
|
|
tests = ("connector_codex_exclusions", "codex_source_containment")
|
|
lines = [
|
|
"[package]", 'name = "cass-codex-contract"', 'version = "0.0.0"',
|
|
'edition = "2024"', "publish = false", "", "[lib]",
|
|
'name = "coding_agent_search"', 'path = "lib.rs"',
|
|
]
|
|
for test in tests:
|
|
lines.extend([
|
|
"", "[[test]]", f'name = "{test}"',
|
|
"path = " + json.dumps((root / f"tests/{test}.rs").as_posix(), ensure_ascii=False),
|
|
])
|
|
lines.extend(["", "[dependencies]"])
|
|
for name in names:
|
|
spec = dependencies[name]
|
|
version = spec if isinstance(spec, str) else spec["version"]
|
|
if name == "franken-agent-detection":
|
|
source = f'version = {json.dumps(version)}'
|
|
if fad_checkout is not None:
|
|
source = f'version = {json.dumps("=" + fad_version)}, path = {json.dumps(fad_checkout.as_posix(), ensure_ascii=False)}'
|
|
lines.append(
|
|
f'{name} = {{ {source}, '
|
|
'default-features = false, features = ["connectors"] }'
|
|
)
|
|
elif name == "serde":
|
|
lines.append(f'{name} = {{ version = {json.dumps(version)}, features = ["derive"] }}')
|
|
else:
|
|
lines.append(f"{name} = {json.dumps(version)}")
|
|
lines.extend(["", "[lints.rust]", 'unsafe_code = "forbid"', ""])
|
|
|
|
library = '''// Re-exports only; the Codex implementation is unmodified production code.
|
|
pub use franken_agent_detection::{
|
|
Connector, DetectionResult, DiscoveredSourceFile, NormalizedConversation,
|
|
NormalizedMessage, ScanContext, ScanRoot, parse_timestamp, reindex_messages,
|
|
};
|
|
pub mod codex;
|
|
pub mod connectors {
|
|
pub use super::{
|
|
Connector, DetectionResult, DiscoveredSourceFile, NormalizedConversation,
|
|
NormalizedMessage, ScanContext, ScanRoot, codex,
|
|
};
|
|
}
|
|
'''
|
|
cargo = shutil.which("cargo")
|
|
if cargo is None:
|
|
raise SystemExit("cargo is required; install the repository's Rust toolchain")
|
|
source_dir = root / "src/connectors"
|
|
source_files = [source_dir / "codex.rs", *sorted((source_dir / "codex").rglob("*.rs"))]
|
|
with tempfile.TemporaryDirectory(prefix="cass-codex-contract-") as directory:
|
|
work = Path(directory)
|
|
project = work / "Cargo.toml"
|
|
project.write_text("\n".join(lines), encoding="utf-8")
|
|
(work / "lib.rs").write_text(library, encoding="utf-8")
|
|
# Normal `mod codex` preserves the nested lookup rules that #[path]
|
|
# overrides. Check equality rather than rewriting source to fit a stub.
|
|
for original in source_files:
|
|
staged = work / original.relative_to(source_dir)
|
|
staged.parent.mkdir(parents=True, exist_ok=True)
|
|
source = original.read_bytes()
|
|
staged.write_bytes(source)
|
|
if staged.read_bytes() != source:
|
|
raise RuntimeError(f"staged source differs from {original}")
|
|
for name in ("Cargo.lock", "rust-toolchain.toml", "rustfmt.toml", ".rustfmt.toml"):
|
|
original = root / name
|
|
if original.is_file():
|
|
shutil.copyfile(original, work / name)
|
|
env = os.environ.copy()
|
|
# The ordinary unit tests must not inherit operator scan exclusions.
|
|
# Integration tests supply each child's own real exclusion value.
|
|
env["CASS_EXCLUDE_PATHS"] = ""
|
|
if fad_checkout is not None:
|
|
metadata = json.loads(subprocess.check_output(
|
|
[cargo, "metadata", "--manifest-path", str(project), "--format-version", "1"],
|
|
cwd=root, env=env, text=True,
|
|
))
|
|
selected = [package for package in metadata["packages"] if package["name"] == "franken-agent-detection"]
|
|
if len(selected) != 1 or Path(selected[0]["manifest_path"]).resolve() != fad_checkout / "Cargo.toml":
|
|
raise RuntimeError("Cargo did not select the requested local FAD checkout")
|
|
print(f"Verified local FAD {fad_version}: {selected[0]['manifest_path']}", flush=True)
|
|
commands = [
|
|
[cargo, "test", "--manifest-path", str(project), "--all-targets"],
|
|
[cargo, "clippy", "--manifest-path", str(project), "--all-targets", "--", "-D", "warnings"],
|
|
]
|
|
for command in commands:
|
|
print("+ " + " ".join(command), flush=True)
|
|
subprocess.run(command, cwd=root, env=env, check=True)
|
|
# Each file is checked individually, so do not resolve its children as
|
|
# if that file were a crate root. Never reformat the actual working tree.
|
|
rustfmt = shutil.which("rustfmt")
|
|
if rustfmt is None:
|
|
raise SystemExit("rustfmt is required")
|
|
command = [
|
|
rustfmt, "--edition", "2024", "--check", "--config", "skip_children=true",
|
|
*map(str, source_files),
|
|
*(str(root / f"tests/{test}.rs") for test in tests),
|
|
]
|
|
print("+ " + " ".join(command), flush=True)
|
|
subprocess.run(command, cwd=root, env=env, check=True)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|