diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a9b89bb..776d854 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -106,6 +106,8 @@ jobs: - run: cargo clippy --workspace --all-targets -- -D warnings - run: cargo build --workspace - run: cargo test --workspace --lib --no-fail-fast + - name: Persist and recover authored memory through the CLI + run: cargo test --locked -p terraphim_agent --test memory_capture_cli_tests --test memory_apply_cli_tests --test memory_rubric_cli_tests # Exercise the released grep command against real files and exported # synonym graphs, including Linux-only hostile filesystem names. - run: cargo test --locked -p terraphim_grep --test synonym_retrieval --test answer_request --test path_guard_hostile_tree diff --git a/Cargo.lock b/Cargo.lock index 216c438..ed56613 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6315,7 +6315,7 @@ dependencies = [ [[package]] name = "terraphim-cli" -version = "1.21.19" +version = "1.21.20" dependencies = [ "anyhow", "assert_cmd", @@ -6356,7 +6356,7 @@ dependencies = [ [[package]] name = "terraphim-session-analyzer" -version = "1.21.19" +version = "1.21.20" dependencies = [ "aho-corasick", "anyhow", @@ -6395,7 +6395,7 @@ dependencies = [ [[package]] name = "terraphim_agent" -version = "1.21.19" +version = "1.21.20" dependencies = [ "ahash", "anyhow", @@ -6580,7 +6580,7 @@ dependencies = [ [[package]] name = "terraphim_grep" -version = "1.21.19" +version = "1.21.20" dependencies = [ "anyhow", "async-trait", @@ -6609,7 +6609,7 @@ dependencies = [ [[package]] name = "terraphim_hooks" -version = "1.21.19" +version = "1.21.20" dependencies = [ "dirs 5.0.1", "serde", @@ -6623,7 +6623,7 @@ dependencies = [ [[package]] name = "terraphim_lsp" -version = "1.21.19" +version = "1.21.20" dependencies = [ "log", "serde", @@ -6650,7 +6650,7 @@ dependencies = [ [[package]] name = "terraphim_mcp_server" -version = "1.21.19" +version = "1.21.20" dependencies = [ "ahash", "anyhow", @@ -6713,7 +6713,7 @@ dependencies = [ [[package]] name = "terraphim_negative_contribution" -version = "1.21.19" +version = "1.21.20" dependencies = [ "log", "terraphim_automata", diff --git a/Cargo.toml b/Cargo.toml index 4fae7af..4f0c63d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ members = [ ] [workspace.package] -version = "1.21.19" +version = "1.21.20" edition = "2024" authors = ["Terraphim Team "] documentation = "https://terraphim.ai" diff --git a/README.md b/README.md index 4666bda..19eddf4 100644 --- a/README.md +++ b/README.md @@ -12,13 +12,14 @@ Consumes upstream crates (core, config-persistence, service, agents, kg-agents) ## Memory Lifecycle -The `terraphim-agent memory` CLI namespace implements the eight-stage agentic memory lifecycle: +The `terraphim-agent memory` namespace saves authored lessons, inspects the +evolution store and retrieves memories through a configured role's knowledge +graph. See [capture and store isolation](docs/memory-capture.md) for a complete +example and the required input change. ``` -terraphim-agent memory capture # Write a memory item with provenance tags -terraphim-agent memory distill # Compile learnings into KG entries +terraphim-agent memory capture --content 'Use the project validation command.' terraphim-agent memory scope # Show role/project KG boundaries -terraphim-agent memory provenance # Search session history terraphim-agent memory retrieve # Search memory items terraphim-agent memory apply # Show hook injection effects terraphim-agent memory validate # Score items against reliability rubric @@ -30,4 +31,11 @@ terraphim-agent memory show # Inspect a specific item terraphim-agent memory export # Dump as JSON or markdown ``` +The full eight-stage lifecycle is not qualified by these commands. In the +current implementation, `memory distill` and `memory provenance` only report +status; `memory scope --check` does not verify confidentiality. Use explicit +`learn compile` / `learn export-kg` for the separate reviewed-learning store. +`memory apply` previews context; it does not execute a command. Rubric and +validation results use the named `heuristic-v1` scorer. + See [MEMORY_POLICY.md](MEMORY_POLICY.md) for the public commons vs permissioned memory boundary. diff --git a/crates/terraphim_agent/src/cli_schema.rs b/crates/terraphim_agent/src/cli_schema.rs index 314ca6b..70e755d 100644 --- a/crates/terraphim_agent/src/cli_schema.rs +++ b/crates/terraphim_agent/src/cli_schema.rs @@ -782,9 +782,14 @@ pub(crate) enum RobotSub { #[derive(Subcommand, Debug)] pub(crate) enum MemorySub { - /// Capture a command or session event as an agentic memory item - /// (writes to evolution store with provenance metadata) + /// Save authored lesson text to the evolution store with provenance metadata Capture { + /// Exact lesson text to save (mutually exclusive with --file) + #[arg(long, required_unless_present = "file", conflicts_with = "file")] + content: Option, + /// Read the lesson from a UTF-8 file (mutually exclusive with --content) + #[arg(long, required_unless_present = "content", conflicts_with = "content")] + file: Option, /// Provenance tag for traceability (session ID, commit SHA) #[arg(long)] provenance_tag: Option, diff --git a/crates/terraphim_agent/src/main.rs b/crates/terraphim_agent/src/main.rs index e0b2595..3eced68 100644 --- a/crates/terraphim_agent/src/main.rs +++ b/crates/terraphim_agent/src/main.rs @@ -2505,7 +2505,11 @@ async fn run_cache_command(sub: &CacheSub) -> Result<()> { } fn evolution_path() -> std::path::PathBuf { - dirs::config_dir() + // Use the same explicit data root as learning capture. Existing users + // without an override retain the historical config-directory location. + std::env::var_os("TERRAPHIM_DEFAULT_DATA_PATH") + .map(std::path::PathBuf::from) + .or_else(dirs::config_dir) .unwrap_or_else(|| std::path::PathBuf::from(".")) .join("terraphim") .join("evolution") diff --git a/crates/terraphim_agent/src/memory_command.rs b/crates/terraphim_agent/src/memory_command.rs index 75b329d..0750a09 100644 --- a/crates/terraphim_agent/src/memory_command.rs +++ b/crates/terraphim_agent/src/memory_command.rs @@ -7,7 +7,7 @@ //! `compute_risk`) that only this command uses. Extracted verbatim; only the //! imports are new. -use anyhow::Result; +use anyhow::{Context, Result}; use terraphim_agent::service::TuiService; @@ -20,14 +20,28 @@ pub(crate) async fn run_memory_command( config_path: Option, ) -> Result<()> { match sub { - MemorySub::Capture { provenance_tag } => { + MemorySub::Capture { + content, + file, + provenance_tag, + } => { use terraphim_agent_evolution::{ImportanceLevel, MemoryItem, MemoryItemType}; + let content = match (content, file) { + (Some(content), None) => content, + (None, Some(path)) => std::fs::read_to_string(&path).with_context(|| { + format!("Cannot read memory lesson from {}", path.display()) + })?, + _ => anyhow::bail!("Provide exactly one of --content or --file"), + }; + anyhow::ensure!( + !content.trim().is_empty(), + "Memory lesson must not be blank" + ); + // Validate before loading or saving the store. The evolution crate + // enforces the same byte limit when adding the MemoryItem. + anyhow::ensure!(content.len() <= 1_000_000, "Memory lesson exceeds 1 MB"); let mut evolution = load_evolution(); - let content = provenance_tag - .as_ref() - .map(|tag| format!("Memory item captured via CLI with provenance: {}", tag)) - .unwrap_or_else(|| "Memory item captured via CLI".to_string()); let tags: Vec = provenance_tag .clone() .map(|tag| vec![format!("provenance:{}", tag)]) diff --git a/crates/terraphim_agent/tests/memory_apply_cli_tests.rs b/crates/terraphim_agent/tests/memory_apply_cli_tests.rs index ebe9081..177d2a2 100644 --- a/crates/terraphim_agent/tests/memory_apply_cli_tests.rs +++ b/crates/terraphim_agent/tests/memory_apply_cli_tests.rs @@ -12,8 +12,8 @@ //! at `tests/test_kg/`) and the evolution store lives under a temp `HOME`. //! No mocks: the store file is the one the binary writes. //! -//! `memory capture` writes fixed content with no knowledge-graph term in it, -//! so a captured item alone is never retrieved and the injected size is zero. +//! The baseline captures content with no knowledge-graph term in it, +//! so that item is not retrieved and the injected size is zero. //! The non-zero case adds an item whose content names the `trash` concept //! twice (`rm -rf` and `rm -r`), through the real `MemoryState::add_memory`, //! into the store the CLI created. @@ -53,6 +53,8 @@ fn capture_item(root: &Path, tag: &str) -> String { "json", "memory", "capture", + "--content", + "A baseline note with no configured concepts.", "--provenance-tag", tag, ], diff --git a/crates/terraphim_agent/tests/memory_capture_cli_tests.rs b/crates/terraphim_agent/tests/memory_capture_cli_tests.rs new file mode 100644 index 0000000..e2929bf --- /dev/null +++ b/crates/terraphim_agent/tests/memory_capture_cli_tests.rs @@ -0,0 +1,134 @@ +//! Exercise authored memory through the actual CLI and persisted store. + +use std::path::Path; +use std::process::{Command, Output}; + +fn run(root: &Path, args: &[&str]) -> Output { + Command::new(env!("CARGO_BIN_EXE_terraphim-agent")) + .args(["--format", "json"]) + .args(args) + .env("TERRAPHIM_DEFAULT_DATA_PATH", root) + .current_dir(root) + .output() + .expect("run real agent") +} + +fn json(output: Output) -> serde_json::Value { + assert!( + output.status.success(), + "{}", + String::from_utf8_lossy(&output.stderr) + ); + serde_json::from_slice(&output.stdout).expect("machine-readable result") +} + +#[test] +fn capture_preserves_authored_content_across_processes_and_stores() { + let root = tempfile::tempdir().unwrap(); + let other = tempfile::tempdir().unwrap(); + let content = "Validate the public garden brief with python3 validate.py --brief brief.md.\nKeep the source decisions intact."; + let captured = json(run( + root.path(), + &[ + "memory", + "capture", + "--content", + content, + "--provenance-tag", + "public-fixture-v1", + ], + )); + let id = captured["memory_id"].as_str().unwrap(); + let shown = json(run(root.path(), &["memory", "show", id])); + assert_eq!(shown["memory_item"]["content"], content); + assert_eq!( + shown["memory_item"]["tags"][0], + "provenance:public-fixture-v1" + ); + let store = root.path().join("terraphim/evolution/cli-agent.json"); + assert!( + store.is_file(), + "explicit data root owns the persisted store" + ); + let listed = json(run(root.path(), &["memory", "list"])); + assert!(listed.to_string().contains(id)); + let exported = json(run(root.path(), &["memory", "export", "--format", "json"])); + assert!( + exported + .to_string() + .contains("Keep the source decisions intact.") + ); + let isolated = json(run(other.path(), &["memory", "list"])); + assert!(!isolated.to_string().contains(id)); + assert!( + !other + .path() + .join("terraphim/evolution/cli-agent.json") + .exists() + ); +} + +#[test] +fn capture_reads_utf8_file_without_replacing_content_with_provenance() { + let root = tempfile::tempdir().unwrap(); + let input = root.path().join("lesson.md"); + let content = "# Validation lesson\nUse the café fixture — keep Ελληνικά intact.\n"; + std::fs::write(&input, content).unwrap(); + let captured = json(run( + root.path(), + &["memory", "capture", "--file", input.to_str().unwrap()], + )); + let shown = json(run( + root.path(), + &["memory", "show", captured["memory_id"].as_str().unwrap()], + )); + assert_eq!(shown["memory_item"]["content"], content); +} + +#[test] +fn capture_refuses_missing_blank_conflicting_and_unreadable_input() { + for args in [ + vec!["memory", "capture"], + vec!["memory", "capture", "--content", " \n\t"], + vec!["memory", "capture", "--file", "missing-lesson.md"], + vec![ + "memory", + "capture", + "--content", + "lesson", + "--file", + "lesson.md", + ], + ] { + let root = tempfile::tempdir().unwrap(); + let output = run(root.path(), &args); + assert!(!output.status.success(), "must reject {args:?}"); + assert!( + !root + .path() + .join("terraphim/evolution/cli-agent.json") + .exists() + ); + } +} + +#[test] +fn invalid_files_leave_existing_memories_unchanged() { + let root = tempfile::tempdir().unwrap(); + json(run( + root.path(), + &["memory", "capture", "--content", "Keep this authored note."], + )); + let store = root.path().join("terraphim/evolution/cli-agent.json"); + let before = std::fs::read(&store).unwrap(); + for bytes in [vec![0xff, 0xfe], vec![b'a'; 1_000_001], b" \n\t".to_vec()] { + let input = root.path().join("invalid-lesson.md"); + std::fs::write(&input, bytes).unwrap(); + let output = run( + root.path(), + &["memory", "capture", "--file", input.to_str().unwrap()], + ); + assert!(!output.status.success()); + assert_eq!(std::fs::read(&store).unwrap(), before); + } +} diff --git a/crates/terraphim_agent/tests/memory_rubric_cli_tests.rs b/crates/terraphim_agent/tests/memory_rubric_cli_tests.rs index 508b27c..fa64e7c 100644 --- a/crates/terraphim_agent/tests/memory_rubric_cli_tests.rs +++ b/crates/terraphim_agent/tests/memory_rubric_cli_tests.rs @@ -58,6 +58,8 @@ fn capture_medium_item(home: &Path) -> String { "json", "memory", "capture", + "--content", + "A baseline note for rubric inspection.", "--provenance-tag", "rubric-cli-test", ], diff --git a/docs/memory-capture.md b/docs/memory-capture.md new file mode 100644 index 0000000..9b2310c --- /dev/null +++ b/docs/memory-capture.md @@ -0,0 +1,41 @@ +# Save a lesson and recover it in another process + +`memory capture` requires the actual lesson, either as `--content` or a UTF-8 +`--file`. A provenance tag identifies the source; it is not a substitute for +the lesson. Blank, unreadable and conflicting inputs fail without writing a +memory. Content is preserved exactly, up to the evolution crate's 1 MB limit. + +```sh +export TERRAPHIM_DEFAULT_DATA_PATH="$PWD/.terraphim-demo-data" +terraphim-agent --format json memory capture \ + --content 'Validate the garden brief with python3 validate.py --brief brief.md.' \ + --provenance-tag public-brief-v1 +terraphim-agent --format json memory list +terraphim-agent --format json memory show MEMORY_ID_FROM_CAPTURE +terraphim-agent memory export --format json --output memories.json +``` + +These commands each start a new process. With the explicit data root, the +evolution store is `.terraphim-demo-data/terraphim/evolution/cli-agent.json`. +Without it, the historical platform configuration-directory path is retained; +existing stores are not moved or imported. Use a different data root for a +separate project store. This is file-location isolation, not an access-control +system or automatic secret redaction. + +To save a multiline note, use `memory capture --file lesson.md`. Text and file +input are mutually exclusive. Earlier versions accepted capture with only a +provenance tag and saved placeholder text; callers must now supply content. + +Retrieval is a separate operation using the selected role's knowledge graph: + +```sh +terraphim-agent --config role-config.json memory retrieve 'validate brief' \ + --role 'Brief Reviewer' --format json +``` + +Configure that role and its graph before retrieval. Saving a lesson does not +create terminology or copy it into the separate `learn` store. Graph retrieval +requires concept co-occurrence in the lesson; a role that does not recognise +the query returns no memories rather than a lexical fallback. A role is a +retrieval configuration, not a confidentiality boundary. `memory apply` is a +preview of proposed context and does not execute commands. diff --git a/docs/verification/memory-capture-2026-10-13.md b/docs/verification/memory-capture-2026-10-13.md new file mode 100644 index 0000000..3164d6a --- /dev/null +++ b/docs/verification/memory-capture-2026-10-13.md @@ -0,0 +1,36 @@ +# Authored memory capture verification + +The public v1.21.19 agent rejected `--content`, ignored lesson text on stdin and +saved only provenance placeholder text. A positive role-graph query consequently +returned zero memory items. A three-test regression run against the pre-fix code +failed as expected. Tests now require actual input and the explicit data-root +store, so the placeholder behavior cannot satisfy the successful capture cases. + +The fix adds required `--content` or UTF-8 `--file`, rejects blank/unreadable/ +conflicting/oversized input, and preserves the supplied text exactly. It reuses +`MemoryItem` and the existing evolution crate. `TERRAPHIM_DEFAULT_DATA_PATH` +selects the evolution root; without it the historical location is unchanged. + +Validation on macOS ARM64 using the CI-pinned Rust 1.96.0: + +- 12 CLI tests passed across `memory_capture_cli_tests`, `memory_apply_cli_tests` + and `memory_rubric_cli_tests`. +- Invalid UTF-8, blank and >1 MB files leave an existing store byte-identical. +- `cargo clippy -p terraphim_agent --all-targets -- -D warnings` passed. +- `cargo fmt --all -- --check` and `git diff --check` passed. +- Independent execution recovered the exact public lesson through a fresh + process and role graph. Positive query: one item; unrelated query, other role + and independent empty store: zero. Unicode content was preserved. + +Independent code review found no blocking defect; the requested documentation +and invalid-file tests were added. The initial Mac-default Rust 1.99 lint run +failed on unrelated async-trait `double_must_use` diagnostics in sessions; the +repository's pinned 1.96.0 lint gate passed without suppressing those lints. + +This is candidate verification, not released-binary acceptance. After CI and +release production, download v1.21.20, verify its published checksum and repeat +the demonstration before publishing the website article/video. + +The remaining `memory distill`, `memory provenance` and confidentiality-check +stubs are not qualified by this scoped fix or advertised as working in its +walkthrough. Role-based retrieval is not an access-control boundary. diff --git a/pkgbuilds/terraphim-clients-bin/.SRCINFO b/pkgbuilds/terraphim-clients-bin/.SRCINFO index 43d4e0f..a6dbbe2 100644 --- a/pkgbuilds/terraphim-clients-bin/.SRCINFO +++ b/pkgbuilds/terraphim-clients-bin/.SRCINFO @@ -1,6 +1,6 @@ pkgbase = terraphim-clients-bin pkgdesc = Terraphim AI command-line clients (prebuilt static MUSL binaries) - pkgver = 1.21.19 + pkgver = 1.21.20 pkgrel = 1 url = https://terraphim.ai arch = x86_64 @@ -9,14 +9,14 @@ pkgbase = terraphim-clients-bin license = MIT options = !strip options = !debug - source_x86_64 = terraphim-agent-1.21.19-x86_64-unknown-linux-musl.tar.gz::https://github.com/terraphim/terraphim-clients/releases/download/v1.21.19/terraphim-agent-1.21.19-x86_64-unknown-linux-musl.tar.gz - source_x86_64 = terraphim-grep-1.21.19-x86_64-unknown-linux-musl.tar.gz::https://github.com/terraphim/terraphim-clients/releases/download/v1.21.19/terraphim-grep-1.21.19-x86_64-unknown-linux-musl.tar.gz - sha256sums_x86_64 = 6970a26f1d33cad67a78397c6d18d6ca0b5d56200b7d86be3027199ca5d1d5d9 - sha256sums_x86_64 = d95ae22a7a84c294e700e957ff94ad25195481fce80ea7673a240c6240257220 - source_aarch64 = terraphim-agent-1.21.19-aarch64-unknown-linux-musl.tar.gz::https://github.com/terraphim/terraphim-clients/releases/download/v1.21.19/terraphim-agent-1.21.19-aarch64-unknown-linux-musl.tar.gz - source_aarch64 = terraphim-grep-1.21.19-aarch64-unknown-linux-musl.tar.gz::https://github.com/terraphim/terraphim-clients/releases/download/v1.21.19/terraphim-grep-1.21.19-aarch64-unknown-linux-musl.tar.gz - sha256sums_aarch64 = 5c763fb2308f3d83d3e83f935bfa77a9c90414ec7567eac275bedbc7c179e103 - sha256sums_aarch64 = 1332b48c1ca67e0d2ffd534f5a112c77ffea5885004cbd1909e7ac0aecd2f086 + source_x86_64 = terraphim-agent-1.21.20-x86_64-unknown-linux-musl.tar.gz::https://github.com/terraphim/terraphim-clients/releases/download/v1.21.20/terraphim-agent-1.21.20-x86_64-unknown-linux-musl.tar.gz + source_x86_64 = terraphim-grep-1.21.20-x86_64-unknown-linux-musl.tar.gz::https://github.com/terraphim/terraphim-clients/releases/download/v1.21.20/terraphim-grep-1.21.20-x86_64-unknown-linux-musl.tar.gz + sha256sums_x86_64 = 242c3a72849d3e905c3af6359002fb7473c900df2f4c87ccdebe80c0c538e4ce + sha256sums_x86_64 = 6930c335bb41caab26eb8b1f7e5ef2bc19ef6dfabd17abeb584f1672f54c1d0d + source_aarch64 = terraphim-agent-1.21.20-aarch64-unknown-linux-musl.tar.gz::https://github.com/terraphim/terraphim-clients/releases/download/v1.21.20/terraphim-agent-1.21.20-aarch64-unknown-linux-musl.tar.gz + source_aarch64 = terraphim-grep-1.21.20-aarch64-unknown-linux-musl.tar.gz::https://github.com/terraphim/terraphim-clients/releases/download/v1.21.20/terraphim-grep-1.21.20-aarch64-unknown-linux-musl.tar.gz + sha256sums_aarch64 = cf09f161ff42180308509d8e9b43b66c94bedd3801987cd1112b38b3718b5789 + sha256sums_aarch64 = 320690a756083cccac28c11d918f549e7a7e1fbcbce31250388d6638087215d8 pkgname = terraphim-agent-bin pkgdesc = Terraphim AI agent CLI (prebuilt static MUSL binary) diff --git a/pkgbuilds/terraphim-clients-bin/PKGBUILD b/pkgbuilds/terraphim-clients-bin/PKGBUILD index 0697e5f..f293556 100644 --- a/pkgbuilds/terraphim-clients-bin/PKGBUILD +++ b/pkgbuilds/terraphim-clients-bin/PKGBUILD @@ -18,7 +18,7 @@ pkgbase=terraphim-clients-bin pkgname=(terraphim-agent-bin terraphim-grep-bin) -pkgver=1.21.19 +pkgver=1.21.20 pkgrel=1 pkgdesc='Terraphim AI command-line clients (prebuilt static MUSL binaries)' arch=('x86_64' 'aarch64') @@ -45,12 +45,12 @@ source_aarch64=( # SHA256SUMS asset for v${pkgver}. tests/test_pkgbuild_release_contract.py pins # the same values so a version bump cannot silently keep stale digests. sha256sums_x86_64=( - '6970a26f1d33cad67a78397c6d18d6ca0b5d56200b7d86be3027199ca5d1d5d9' - 'd95ae22a7a84c294e700e957ff94ad25195481fce80ea7673a240c6240257220' + '242c3a72849d3e905c3af6359002fb7473c900df2f4c87ccdebe80c0c538e4ce' + '6930c335bb41caab26eb8b1f7e5ef2bc19ef6dfabd17abeb584f1672f54c1d0d' ) sha256sums_aarch64=( - '5c763fb2308f3d83d3e83f935bfa77a9c90414ec7567eac275bedbc7c179e103' - '1332b48c1ca67e0d2ffd534f5a112c77ffea5885004cbd1909e7ac0aecd2f086' + 'cf09f161ff42180308509d8e9b43b66c94bedd3801987cd1112b38b3718b5789' + '320690a756083cccac28c11d918f549e7a7e1fbcbce31250388d6638087215d8' ) # Prebuilt, already-stripped static binaries: never strip or emit debug info. diff --git a/scripts/memory_apply_fixture_queries.py b/scripts/memory_apply_fixture_queries.py index ed8d076..fe82173 100755 --- a/scripts/memory_apply_fixture_queries.py +++ b/scripts/memory_apply_fixture_queries.py @@ -96,7 +96,7 @@ def run(*args): return json.loads(proc.stdout.strip().splitlines()[-1]) # Create the store through the real CLI, then seed it with the fixture corpus. - run("memory", "capture", "--provenance-tag", "memory-benchmark-doc") + run("memory", "capture", "--content", "Benchmark baseline note.", "--provenance-tag", "memory-benchmark-doc") store = next(root.rglob("cli-agent.json")) envelope = json.load(open(store)) items = [json.loads(line) for line in open(fixture / "corpus.jsonl") if line.strip()] diff --git a/tests/test_pkgbuild_release_contract.py b/tests/test_pkgbuild_release_contract.py index 5ebaaf6..86f17eb 100644 --- a/tests/test_pkgbuild_release_contract.py +++ b/tests/test_pkgbuild_release_contract.py @@ -32,7 +32,7 @@ # publication. During a release window (workspace bumped, signed assets not # yet sealed) this contract intentionally fails until the follow-up PKGBUILD # bump lands. -PKGVER = "1.21.19" +PKGVER = "1.21.20" REPO = "terraphim/terraphim-clients" RELEASE_BASE = f"https://github.com/{REPO}/releases/download/v{PKGVER}" @@ -41,21 +41,21 @@ "x86_64": { "terraphim-agent": ( f"terraphim-agent-{PKGVER}-x86_64-unknown-linux-musl.tar.gz", - "6970a26f1d33cad67a78397c6d18d6ca0b5d56200b7d86be3027199ca5d1d5d9", + "242c3a72849d3e905c3af6359002fb7473c900df2f4c87ccdebe80c0c538e4ce", ), "terraphim-grep": ( f"terraphim-grep-{PKGVER}-x86_64-unknown-linux-musl.tar.gz", - "d95ae22a7a84c294e700e957ff94ad25195481fce80ea7673a240c6240257220", + "6930c335bb41caab26eb8b1f7e5ef2bc19ef6dfabd17abeb584f1672f54c1d0d", ), }, "aarch64": { "terraphim-agent": ( f"terraphim-agent-{PKGVER}-aarch64-unknown-linux-musl.tar.gz", - "5c763fb2308f3d83d3e83f935bfa77a9c90414ec7567eac275bedbc7c179e103", + "cf09f161ff42180308509d8e9b43b66c94bedd3801987cd1112b38b3718b5789", ), "terraphim-grep": ( f"terraphim-grep-{PKGVER}-aarch64-unknown-linux-musl.tar.gz", - "1332b48c1ca67e0d2ffd534f5a112c77ffea5885004cbd1909e7ac0aecd2f086", + "320690a756083cccac28c11d918f549e7a7e1fbcbce31250388d6638087215d8", ), }, } diff --git a/tests/test_release_binaries_workflow_contract.py b/tests/test_release_binaries_workflow_contract.py index f1dfdd4..30dba3a 100644 --- a/tests/test_release_binaries_workflow_contract.py +++ b/tests/test_release_binaries_workflow_contract.py @@ -176,7 +176,7 @@ def test_preflight_recursively_peels_to_exact_expected_sha(self) -> None: def test_release_uses_checked_in_version_and_never_mutates_source(self) -> None: text = workflow_text() workspace = tomllib.loads((ROOT / "Cargo.toml").read_text()) - self.assertEqual(workspace["workspace"]["package"]["version"], "1.21.19") + self.assertEqual(workspace["workspace"]["package"]["version"], "1.21.20") for forbidden in ( "Set release version", "set_section_version",