From 8ea814850d3e4f3c9a52a12cf8e7a07fede7fbef Mon Sep 17 00:00:00 2001 From: t Date: Sun, 25 Oct 2026 08:19:41 +0100 Subject: [PATCH 1/4] chore(roadmap): entries for PMAT-5446, PMAT-5909 and PMAT-5803 so #6294 and #6309 split by ticket PMAT-5446 covers the #5893 planted-.pv tests carried by #6309 (issue #5446: slow contracts-cli ont4 gate tests); PMAT-5909 and PMAT-5803 take their scope from #6294. Entries plus the regenerated aggregate only. PMAT-Ticket: PMAT-5446 Co-Authored-By: Claude Sonnet 5.5 --- docs/roadmaps/entries/PMAT-5446.yaml | 22 +++++++++ docs/roadmaps/entries/PMAT-5803.yaml | 23 ++++++++++ docs/roadmaps/entries/PMAT-5909.yaml | 23 ++++++++++ docs/roadmaps/roadmap.yaml | 68 ++++++++++++++++++++++++++++ 4 files changed, 136 insertions(+) create mode 100644 docs/roadmaps/entries/PMAT-5446.yaml create mode 100644 docs/roadmaps/entries/PMAT-5803.yaml create mode 100644 docs/roadmaps/entries/PMAT-5909.yaml diff --git a/docs/roadmaps/entries/PMAT-5446.yaml b/docs/roadmaps/entries/PMAT-5446.yaml new file mode 100644 index 0000000000..50606c00b7 --- /dev/null +++ b/docs/roadmaps/entries/PMAT-5446.yaml @@ -0,0 +1,22 @@ +- id: PMAT-5446 + github_issue: 5446 + item_type: task + title: 'ci: shrink the slow quick-tier tests (apr-cli test_llm_band, contracts-cli ont4 gate tests) at the root' + status: in_progress + priority: medium + assigned_to: null + created: 2026-10-25T07:50:00Z + updated: 2026-10-25T07:50:00Z + spec: null + acceptance_criteria: + - 'contracts-cli ont4_relations_gate, ont4b_shapes_gate and ont5_consistency_gate lint a planted fixture or copied files, not the full contracts tree, and each finishes well under 60 s (landed by #5893 via the EMR-001 integration PR #6309)' + - the pv-sat corpus() lint tests use a planted .pv fixture (same change) + - apr-cli commands::test_llm_band tests no longer take 60-240 s each (separate PR; not covered by #6309) + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: |- + Entry minted for the #5893 planted-.pv tests carried by #6309 (quorum handoff triage-quorum-tickets-6294-6309-0718Z). Issue #5446 names both slow families; #5893 is the contracts-cli half (gate tests lint a fixture, 11/11 per its body). The test_llm_band half has no PR yet, so the item stays in_progress. + epic: null diff --git a/docs/roadmaps/entries/PMAT-5803.yaml b/docs/roadmaps/entries/PMAT-5803.yaml new file mode 100644 index 0000000000..122a4e256e --- /dev/null +++ b/docs/roadmaps/entries/PMAT-5803.yaml @@ -0,0 +1,23 @@ +- id: PMAT-5803 + github_issue: 5803 + item_type: task + title: 'build: FLOW-010 cut 1 — move the tuner tests that need aprender-core out of aprender-compute so compute drops its dev-dependency on core' + status: in_progress + priority: medium + assigned_to: null + created: 2026-10-25T07:50:00Z + updated: 2026-10-25T07:50:00Z + spec: null + acceptance_criteria: + - the tuner training-data-quality tests move from crates/aprender-compute/tests/tuner_falsification to crates/aprender-core/tests/tuner_training_data_quality.rs and still run (ci/explicit-test-commands.d fragments 295 and 298 name them) + - aprender-compute has no dev-dependency on aprender-core + - scripts/check_tuner_test_move.sh proves the move lost no test (count and names before and after) + - one PR, at most 400 lines or a recorded PMAT-Size-Waiver (the move was 810 lines in #6294 commit ebf773587a, waiver sanctioned by quorum triage-quorum-door6261-conditions-2136Z) + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: |- + Scope taken from #6294 (commit 2, PMAT-5803; issue #5803, FLOW-010 five-whys on crate fan-out, cut 1). Entry minted so w5032 can cut this piece as its own PR. + epic: null diff --git a/docs/roadmaps/entries/PMAT-5909.yaml b/docs/roadmaps/entries/PMAT-5909.yaml new file mode 100644 index 0000000000..2563051515 --- /dev/null +++ b/docs/roadmaps/entries/PMAT-5909.yaml @@ -0,0 +1,23 @@ +- id: PMAT-5909 + github_issue: 5909 + item_type: task + title: 'build: split env_key out of aprender-contracts into aprender-contracts-key so a contracts edit stops dirtying 47 of 85 crates' + status: in_progress + priority: medium + assigned_to: null + created: 2026-10-25T07:50:00Z + updated: 2026-10-25T07:50:00Z + spec: null + acceptance_criteria: + - a new crate crates/aprender-contracts-key holds env_key (src/lib.rs, README, Cargo.toml) and aprender-contracts re-uses it through build_helper + - the build.rs and Cargo.toml of each dependent crate (aprender-core, -compute, -db, -orchestrate, -present-cli, -present-core, -rag, -serve, -simulate, -train, -viz-ttop) depend on aprender-contracts-key instead of aprender-contracts + - cargo metadata --locked is clean and the crate is registered in scripts/release/publish-order.txt and scripts/cascade-publish.sh; publishing it stays on the release path + - one PR, at most 400 lines, no Sensitive-path change beyond the workspace member and publish order lines (cut from #6294 commit 4b8f637715) + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: |- + Scope taken from #6294 (commit 1, PMAT-5909; issue #5909: aprender-contracts is 24 commits in 30 days and dirties 47 of 85 crates). #6294 is split by quorum triage-quorum-tickets-6294-6309-0718Z into one PR per ticket; this entry lets w5032 cut this piece. + epic: null diff --git a/docs/roadmaps/roadmap.yaml b/docs/roadmaps/roadmap.yaml index b5bd1bc998..5f1bb142f2 100644 --- a/docs/roadmaps/roadmap.yaml +++ b/docs/roadmaps/roadmap.yaml @@ -25319,6 +25319,28 @@ Not done, pending the ruling: moving the 31 fixture files to an obviously synthe - kind:code notes: null epic: 4780 +- id: PMAT-5446 + github_issue: 5446 + item_type: task + title: 'ci: shrink the slow quick-tier tests (apr-cli test_llm_band, contracts-cli ont4 gate tests) at the root' + status: in_progress + priority: medium + assigned_to: null + created: 2026-10-25T07:50:00Z + updated: 2026-10-25T07:50:00Z + spec: null + acceptance_criteria: + - 'contracts-cli ont4_relations_gate, ont4b_shapes_gate and ont5_consistency_gate lint a planted fixture or copied files, not the full contracts tree, and each finishes well under 60 s (landed by #5893 via the EMR-001 integration PR #6309)' + - the pv-sat corpus() lint tests use a planted .pv fixture (same change) + - apr-cli commands::test_llm_band tests no longer take 60-240 s each (separate PR; not covered by #6309) + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: |- + Entry minted for the #5893 planted-.pv tests carried by #6309 (quorum handoff triage-quorum-tickets-6294-6309-0718Z). Issue #5446 names both slow families; #5893 is the contracts-cli half (gate tests lint a fixture, 11/11 per its body). The test_llm_band half has no PR yet, so the item stays in_progress. + epic: null - id: PMAT-5463 github_issue: 5463 item_type: task @@ -25375,6 +25397,29 @@ Not done, pending the ruling: moving the 31 fixture files to an obviously synthe - kind:code notes: null epic: 3863 +- id: PMAT-5803 + github_issue: 5803 + item_type: task + title: 'build: FLOW-010 cut 1 — move the tuner tests that need aprender-core out of aprender-compute so compute drops its dev-dependency on core' + status: in_progress + priority: medium + assigned_to: null + created: 2026-10-25T07:50:00Z + updated: 2026-10-25T07:50:00Z + spec: null + acceptance_criteria: + - the tuner training-data-quality tests move from crates/aprender-compute/tests/tuner_falsification to crates/aprender-core/tests/tuner_training_data_quality.rs and still run (ci/explicit-test-commands.d fragments 295 and 298 name them) + - aprender-compute has no dev-dependency on aprender-core + - scripts/check_tuner_test_move.sh proves the move lost no test (count and names before and after) + - one PR, at most 400 lines or a recorded PMAT-Size-Waiver (the move was 810 lines in #6294 commit ebf773587a, waiver sanctioned by quorum triage-quorum-door6261-conditions-2136Z) + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: |- + Scope taken from #6294 (commit 2, PMAT-5803; issue #5803, FLOW-010 five-whys on crate fan-out, cut 1). Entry minted so w5032 can cut this piece as its own PR. + epic: null - id: PMAT-5817 github_issue: 5817 item_type: task @@ -25550,6 +25595,29 @@ Not done, pending the ruling: moving the 31 fixture files to an obviously synthe - kind:measurement notes: null epic: 5510 +- id: PMAT-5909 + github_issue: 5909 + item_type: task + title: 'build: split env_key out of aprender-contracts into aprender-contracts-key so a contracts edit stops dirtying 47 of 85 crates' + status: in_progress + priority: medium + assigned_to: null + created: 2026-10-25T07:50:00Z + updated: 2026-10-25T07:50:00Z + spec: null + acceptance_criteria: + - a new crate crates/aprender-contracts-key holds env_key (src/lib.rs, README, Cargo.toml) and aprender-contracts re-uses it through build_helper + - the build.rs and Cargo.toml of each dependent crate (aprender-core, -compute, -db, -orchestrate, -present-cli, -present-core, -rag, -serve, -simulate, -train, -viz-ttop) depend on aprender-contracts-key instead of aprender-contracts + - cargo metadata --locked is clean and the crate is registered in scripts/release/publish-order.txt and scripts/cascade-publish.sh; publishing it stays on the release path + - one PR, at most 400 lines, no Sensitive-path change beyond the workspace member and publish order lines (cut from #6294 commit 4b8f637715) + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: |- + Scope taken from #6294 (commit 1, PMAT-5909; issue #5909: aprender-contracts is 24 commits in 30 days and dirties 47 of 85 crates). #6294 is split by quorum triage-quorum-tickets-6294-6309-0718Z into one PR per ticket; this entry lets w5032 cut this piece. + epic: null - id: PMAT-5914 github_issue: 5914 item_type: task From 715bcd4b06183ae0b298f747f6ebb6aec125357b Mon Sep 17 00:00:00 2001 From: t Date: Sun, 25 Oct 2026 08:54:58 +0100 Subject: [PATCH 2/4] docs(roadmap): PMAT-5909 criterion 1 states what the code does: aprender-contracts keeps its own env_key.rs, the key crate is a dev-dependency (Refs #5909) PMAT-Ticket: PMAT-5909 Co-Authored-By: Claude Sonnet 5.5 --- docs/roadmaps/entries/PMAT-5909.yaml | 2 +- docs/roadmaps/roadmap.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/roadmaps/entries/PMAT-5909.yaml b/docs/roadmaps/entries/PMAT-5909.yaml index 2563051515..2c550c0768 100644 --- a/docs/roadmaps/entries/PMAT-5909.yaml +++ b/docs/roadmaps/entries/PMAT-5909.yaml @@ -9,7 +9,7 @@ updated: 2026-10-25T07:50:00Z spec: null acceptance_criteria: - - a new crate crates/aprender-contracts-key holds env_key (src/lib.rs, README, Cargo.toml) and aprender-contracts re-uses it through build_helper + - a new crate crates/aprender-contracts-key holds env_key (src/lib.rs, README, Cargo.toml) and aprender-contracts keeps its own src/env_key.rs (included by build.rs and build_helper.rs) and depends on the key crate as a dev-dependency only, where a test asserts the two builders agree - the build.rs and Cargo.toml of each dependent crate (aprender-core, -compute, -db, -orchestrate, -present-cli, -present-core, -rag, -serve, -simulate, -train, -viz-ttop) depend on aprender-contracts-key instead of aprender-contracts - cargo metadata --locked is clean and the crate is registered in scripts/release/publish-order.txt and scripts/cascade-publish.sh; publishing it stays on the release path - one PR, at most 400 lines, no Sensitive-path change beyond the workspace member and publish order lines (cut from #6294 commit 4b8f637715) diff --git a/docs/roadmaps/roadmap.yaml b/docs/roadmaps/roadmap.yaml index 5f1bb142f2..571b77a054 100644 --- a/docs/roadmaps/roadmap.yaml +++ b/docs/roadmaps/roadmap.yaml @@ -25606,7 +25606,7 @@ Not done, pending the ruling: moving the 31 fixture files to an obviously synthe updated: 2026-10-25T07:50:00Z spec: null acceptance_criteria: - - a new crate crates/aprender-contracts-key holds env_key (src/lib.rs, README, Cargo.toml) and aprender-contracts re-uses it through build_helper + - a new crate crates/aprender-contracts-key holds env_key (src/lib.rs, README, Cargo.toml) and aprender-contracts keeps its own src/env_key.rs (included by build.rs and build_helper.rs) and depends on the key crate as a dev-dependency only, where a test asserts the two builders agree - the build.rs and Cargo.toml of each dependent crate (aprender-core, -compute, -db, -orchestrate, -present-cli, -present-core, -rag, -serve, -simulate, -train, -viz-ttop) depend on aprender-contracts-key instead of aprender-contracts - cargo metadata --locked is clean and the crate is registered in scripts/release/publish-order.txt and scripts/cascade-publish.sh; publishing it stays on the release path - one PR, at most 400 lines, no Sensitive-path change beyond the workspace member and publish order lines (cut from #6294 commit 4b8f637715) From b8b96d0b938a3584fd111f0b463f6168a6587136 Mon Sep 17 00:00:00 2001 From: t Date: Sun, 25 Oct 2026 08:21:33 +0100 Subject: [PATCH 3/4] refactor(contracts): env_key lives in aprender-contracts-key; build.rs stops build-depending on the engine (Refs #5909) Piece 1 of the #6294 split (quorum triage-quorum-tickets-6294-6309-0718Z, one PR per ticket). Stacked on #6334 (the PMAT-5909 entry); the 5502 and 5803 scopes are separate PRs. aprender-contracts keeps its own env_key; the key crate is dev-only for it. PMAT-Ticket: PMAT-5909 Co-Authored-By: Claude Sonnet 5.5 --- Cargo.lock | 20 ++++++++++++----- Cargo.toml | 2 ++ crates/aprender-compute/Cargo.toml | 2 +- crates/aprender-compute/build.rs | 2 +- crates/aprender-contracts-key/Cargo.toml | 14 ++++++++++++ crates/aprender-contracts-key/README.md | 14 ++++++++++++ crates/aprender-contracts-key/src/lib.rs | 15 +++++++++++++ crates/aprender-contracts/Cargo.toml | 2 ++ crates/aprender-contracts/src/build_helper.rs | 22 +++++++++++++++++++ crates/aprender-core/Cargo.toml | 2 +- crates/aprender-core/build.rs | 2 +- crates/aprender-db/Cargo.toml | 2 +- crates/aprender-db/build.rs | 6 ++--- crates/aprender-orchestrate/Cargo.toml | 2 +- crates/aprender-orchestrate/build.rs | 8 +++---- crates/aprender-present-cli/Cargo.toml | 2 +- crates/aprender-present-cli/build.rs | 6 ++--- crates/aprender-present-core/Cargo.toml | 2 +- crates/aprender-present-core/build.rs | 4 ++-- crates/aprender-rag/Cargo.toml | 2 +- crates/aprender-rag/build.rs | 6 ++--- crates/aprender-serve/Cargo.toml | 2 +- crates/aprender-serve/build.rs | 4 ++-- crates/aprender-simulate/Cargo.toml | 2 +- crates/aprender-simulate/build.rs | 8 +++---- crates/aprender-train/Cargo.toml | 2 +- crates/aprender-train/build.rs | 4 ++-- crates/aprender-viz-ttop/Cargo.toml | 2 +- crates/aprender-viz-ttop/build.rs | 2 +- scripts/cascade-publish.sh | 2 +- scripts/release/publish-order.txt | 1 + 31 files changed, 118 insertions(+), 48 deletions(-) create mode 100644 crates/aprender-contracts-key/Cargo.toml create mode 100644 crates/aprender-contracts-key/README.md create mode 100644 crates/aprender-contracts-key/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 0ccb3d8ed7..50e1e39cf2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -451,7 +451,7 @@ name = "aprender-compute" version = "0.71.3" dependencies = [ "anyhow", - "aprender-contracts", + "aprender-contracts-key", "aprender-contracts-macros", "aprender-core", "aprender-cuda-edge", @@ -514,6 +514,7 @@ dependencies = [ name = "aprender-contracts" version = "0.71.3" dependencies = [ + "aprender-contracts-key", "aprender-contracts-macros", "blake3", "criterion 0.5.1", @@ -546,6 +547,10 @@ dependencies = [ "tempfile", ] +[[package]] +name = "aprender-contracts-key" +version = "0.71.3" + [[package]] name = "aprender-contracts-macros" version = "0.71.3" @@ -581,6 +586,7 @@ dependencies = [ "aprender-common", "aprender-compute", "aprender-contracts", + "aprender-contracts-key", "aprender-contracts-macros", "aprender-data", "aprender-profile", @@ -707,7 +713,7 @@ dependencies = [ "aprender-build-sha", "aprender-common", "aprender-compute", - "aprender-contracts", + "aprender-contracts-key", "arrow 59.2.0", "axum 0.7.9", "bytemuck", @@ -920,6 +926,7 @@ dependencies = [ "aprender-common", "aprender-compute", "aprender-contracts", + "aprender-contracts-key", "aprender-contracts-macros", "aprender-core", "aprender-cuda-edge", @@ -986,7 +993,7 @@ name = "aprender-present-cli" version = "0.71.3" dependencies = [ "aprender-build-sha", - "aprender-contracts", + "aprender-contracts-key", "aprender-present-yaml", "clap", "notify", @@ -1000,7 +1007,7 @@ dependencies = [ name = "aprender-present-core" version = "0.71.3" dependencies = [ - "aprender-contracts", + "aprender-contracts-key", "aprender-contracts-macros", "criterion 0.7.0", "proptest", @@ -1293,7 +1300,7 @@ version = "0.71.3" dependencies = [ "aprender-common", "aprender-compute", - "aprender-contracts", + "aprender-contracts-key", "aprender-serve", "async-trait", "bincode", @@ -1404,6 +1411,7 @@ dependencies = [ "approx", "aprender-compute", "aprender-contracts", + "aprender-contracts-key", "aprender-contracts-macros", "aprender-core", "aprender-cuda-edge", @@ -1489,6 +1497,7 @@ version = "0.71.3" dependencies = [ "aprender-build-sha", "aprender-contracts", + "aprender-contracts-key", "aprender-contracts-macros", "aprender-present-core", "aprender-present-terminal", @@ -1680,6 +1689,7 @@ dependencies = [ "aprender-common", "aprender-compute", "aprender-contracts", + "aprender-contracts-key", "aprender-contracts-macros", "aprender-core", "aprender-data", diff --git a/Cargo.toml b/Cargo.toml index 71b08df5c4..f811e5a87e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,6 +37,7 @@ members = [ # --- APR-MONO Phase 2b: was provable-contracts --- "crates/aprender-contracts", "crates/aprender-contracts-macros", + "crates/aprender-contracts-key", "crates/aprender-contracts-cli", # EPIC #4232: shared update check + ` update` for every sovereign binary. "crates/aprender-update", @@ -321,6 +322,7 @@ aprender-train-common = { path = "crates/aprender-train-common", version = "0.71 aprender-train-distill = { path = "crates/aprender-train-distill", version = "0.71.3" } aprender-orchestrate = { path = "crates/aprender-orchestrate", version = "0.71.3" } aprender-contracts = { path = "crates/aprender-contracts", version = "0.71.3" } +aprender-contracts-key = { path = "crates/aprender-contracts-key", version = "0.71.3" } aprender-build-sha = { path = "crates/aprender-build-sha", version = "0.71.3" } aprender-rollup = { path = "crates/aprender-rollup", version = "0.71.3" } aprender-profile = { path = "crates/aprender-profile", version = "0.71.3" } diff --git a/crates/aprender-compute/Cargo.toml b/crates/aprender-compute/Cargo.toml index 1aa9e9f4ab..cd30e9ecbf 100644 --- a/crates/aprender-compute/Cargo.toml +++ b/crates/aprender-compute/Cargo.toml @@ -84,7 +84,7 @@ web-sys = { version = "0.3", optional = true, features = ["console"] } hostname = "0.4" [build-dependencies] -provable-contracts = { workspace = true } # #4369: build_helper::env_key, the one CONTRACT_* key builder +aprender-contracts-key = { workspace = true } # #4369, #5909: the one CONTRACT_* key builder (no engine dependency) serde = { version = "1", features = ["derive"] } serde-saphyr = { workspace = true } diff --git a/crates/aprender-compute/build.rs b/crates/aprender-compute/build.rs index 5c02ae8a78..14c0a7d60e 100644 --- a/crates/aprender-compute/build.rs +++ b/crates/aprender-compute/build.rs @@ -36,7 +36,7 @@ struct Binding { /// Convert a contract filename + equation into a canonical env var name. fn env_var_name(contract: &str, equation: &str) -> String { - provable_contracts::build_helper::env_key( + aprender_contracts_key::env_key( contract.trim_end_matches(".yaml").trim_end_matches(".yml"), equation, ) diff --git a/crates/aprender-contracts-key/Cargo.toml b/crates/aprender-contracts-key/Cargo.toml new file mode 100644 index 0000000000..c5a827ff08 --- /dev/null +++ b/crates/aprender-contracts-key/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "aprender-contracts-key" +description = "The one CONTRACT_* env-var key builder shared by build.rs scripts and aprender-contracts (no dependencies, so build-depending on it does not mark the contract engine affected)" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true +keywords = ["verification", "contracts"] +categories = ["development-tools::build-utils"] + +[lints] +workspace = true diff --git a/crates/aprender-contracts-key/README.md b/crates/aprender-contracts-key/README.md new file mode 100644 index 0000000000..4be79576f6 --- /dev/null +++ b/crates/aprender-contracts-key/README.md @@ -0,0 +1,14 @@ +# aprender-contracts-key + +The one `CONTRACT_*` env-var key builder shared by `build.rs` scripts and `aprender-contracts`. + +Part of the [Aprender](https://github.com/paiml/aprender) monorepo (`paiml/aprender`). It has no dependencies on purpose: a crate that build-depends on it does not mark the contract engine affected. + +```rust +let key = aprender_contracts_key::env_key("my-contract", "eq.1"); +assert_eq!(key, "CONTRACT_MY_CONTRACT_EQ_1"); +``` + +## License + +MIT diff --git a/crates/aprender-contracts-key/src/lib.rs b/crates/aprender-contracts-key/src/lib.rs new file mode 100644 index 0000000000..cff26360f9 --- /dev/null +++ b/crates/aprender-contracts-key/src/lib.rs @@ -0,0 +1,15 @@ +//! The `CONTRACT_*` env-var key builder (#4369, #5909). Dependency-free on purpose. + +/// The env var key `#[contract(contract, equation = equation)]` reads. +/// +/// A producer (a consuming crate's `build.rs`) must emit its +/// `cargo:rustc-env` vars under exactly this key, plus `_PRE_COUNT`, +/// `_PRE_`, `_POST_COUNT` and `_POST_`. Call this instead of +/// re-deriving the format: a hand-rolled copy that drifts makes every +/// condition land under a name the macro never reads (#2699 §4). It is +/// tested equal to the macro's own `contract_env_key!`. +pub fn env_key(contract: &str, equation: &str) -> String { + let contract_part = contract.to_uppercase().replace(['-', '.'], "_"); + let equation_part = equation.to_uppercase().replace(['-', '.'], "_"); + format!("CONTRACT_{contract_part}_{equation_part}") +} diff --git a/crates/aprender-contracts/Cargo.toml b/crates/aprender-contracts/Cargo.toml index 7be48d9776..85fcf2fdc1 100644 --- a/crates/aprender-contracts/Cargo.toml +++ b/crates/aprender-contracts/Cargo.toml @@ -48,6 +48,8 @@ criterion = { version = "0.5", features = ["html_reports"] } # Oracle for f16-conversion falsifiers (PMAT-905). `half` is a workspace leaf crate # (no aprender dependency) → dev-dep introduces no cycle. Used only in tests. half = { workspace = true } +# The shared key builder, dev-only: a normal or build dependency would add a unit to the pv build (12-unit budget, ci/sections.yml m5). #5909 +aprender-contracts-key = { path = "../aprender-contracts-key", version = "0.71.3" } [[bench]] name = "benchmarks" diff --git a/crates/aprender-contracts/src/build_helper.rs b/crates/aprender-contracts/src/build_helper.rs index 80b053ac82..d06200786f 100644 --- a/crates/aprender-contracts/src/build_helper.rs +++ b/crates/aprender-contracts/src/build_helper.rs @@ -467,6 +467,28 @@ bindings: } } + /// The shared `aprender-contracts-key` copy (used by other crates' build.rs) must give + /// the same key as this crate's own `env_key` and as the macro (#5909). + #[test] + fn shared_key_crate_agrees_with_env_key_and_the_macro() { + use provable_contracts_macros::contract_env_key; + for (c, e) in [ + ("rmsnorm-kernel-v1", "rmsnorm"), + ("v1.0", "eq.1"), + ("mixed-Case.v2", "Eq-x.y"), + ] { + assert_eq!(aprender_contracts_key::env_key(c, e), env_key(c, e)); + } + assert_eq!( + aprender_contracts_key::env_key("v1.0", "eq.1"), + contract_env_key!("v1.0", "eq.1") + ); + assert_eq!( + aprender_contracts_key::env_key("mixed-Case.v2", "Eq-x.y"), + contract_env_key!("mixed-Case.v2", "Eq-x.y") + ); + } + #[test] fn test_make_env_key_matches_macro_convention() { assert_eq!( diff --git a/crates/aprender-core/Cargo.toml b/crates/aprender-core/Cargo.toml index 2c6a34777c..9fad293538 100644 --- a/crates/aprender-core/Cargo.toml +++ b/crates/aprender-core/Cargo.toml @@ -213,7 +213,7 @@ provable-contracts-macros = { workspace = true } # realizar = { version = "0.6", default-features = false, optional = true } # BLOCKED [build-dependencies] -provable-contracts = { workspace = true } # #4369: build_helper::env_key, the one CONTRACT_* key builder +aprender-contracts-key = { workspace = true } # #4369, #5909: the one CONTRACT_* key builder (no engine dependency) serde = { version = "1", features = ["derive"] } serde-saphyr = { workspace = true } diff --git a/crates/aprender-core/build.rs b/crates/aprender-core/build.rs index 997babbe67..c0e29dc397 100644 --- a/crates/aprender-core/build.rs +++ b/crates/aprender-core/build.rs @@ -50,7 +50,7 @@ struct Binding { /// /// "softmax-kernel-v1.yaml" + "softmax" -> "CONTRACT_SOFTMAX_KERNEL_V1_SOFTMAX" fn binding_env_var_name(contract: &str, equation: &str) -> String { - provable_contracts::build_helper::env_key( + aprender_contracts_key::env_key( contract.trim_end_matches(".yaml").trim_end_matches(".yml"), equation, ) diff --git a/crates/aprender-db/Cargo.toml b/crates/aprender-db/Cargo.toml index f60b03b5c6..a2cab3378c 100644 --- a/crates/aprender-db/Cargo.toml +++ b/crates/aprender-db/Cargo.toml @@ -66,7 +66,7 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } [build-dependencies] -provable-contracts = { workspace = true } # #4369: build_helper::env_key, the one CONTRACT_* key builder +aprender-contracts-key = { workspace = true } # #4369, #5909: the one CONTRACT_* key builder (no engine dependency) aprender-build-sha = { workspace = true } # #4219: APR_GIT_SHA for --version serde = { version = "1", features = ["derive"] } serde-saphyr = { workspace = true } diff --git a/crates/aprender-db/build.rs b/crates/aprender-db/build.rs index dcc8913930..ffb4d4d655 100644 --- a/crates/aprender-db/build.rs +++ b/crates/aprender-db/build.rs @@ -49,10 +49,8 @@ fn main() { let total = bindings.bindings.len() as u32; for b in &bindings.bindings { - let var = provable_contracts::build_helper::env_key( - b.contract.trim_end_matches(".yaml"), - &b.equation, - ); + let var = + aprender_contracts_key::env_key(b.contract.trim_end_matches(".yaml"), &b.equation); println!("cargo:rustc-env={var}={}", b.status); if b.status == "implemented" { implemented += 1; diff --git a/crates/aprender-orchestrate/Cargo.toml b/crates/aprender-orchestrate/Cargo.toml index 0d2a522d2d..99b8774af5 100644 --- a/crates/aprender-orchestrate/Cargo.toml +++ b/crates/aprender-orchestrate/Cargo.toml @@ -317,7 +317,7 @@ sovereign-stack = [ ] [build-dependencies] -provable-contracts = { workspace = true } # #4369: build_helper::env_key, the one CONTRACT_* key builder +aprender-contracts-key = { workspace = true } # #4369, #5909: the one CONTRACT_* key builder (no engine dependency) aprender-build-sha = { workspace = true } # #4219: APR_GIT_SHA for --version serde = { version = "1", features = ["derive"] } serde-saphyr = { workspace = true } diff --git a/crates/aprender-orchestrate/build.rs b/crates/aprender-orchestrate/build.rs index 8f14315f0c..2fba89145c 100644 --- a/crates/aprender-orchestrate/build.rs +++ b/crates/aprender-orchestrate/build.rs @@ -80,10 +80,8 @@ fn emit_bindings(bindings: &BindingFile) { let total = bindings.bindings.len() as u32; for b in &bindings.bindings { - let var = provable_contracts::build_helper::env_key( - b.contract.trim_end_matches(".yaml"), - &b.equation, - ); + let var = + aprender_contracts_key::env_key(b.contract.trim_end_matches(".yaml"), &b.equation); println!("cargo:rustc-env={var}={}", b.status); if b.status == "implemented" { implemented += 1; @@ -117,7 +115,7 @@ fn emit_contract_assertions(cdir: &Path) { continue; }; for (n, eq) in &y.equations { - let k = provable_contracts::build_helper::env_key(&s, n); + let k = aprender_contracts_key::env_key(&s, n); tp += emit_conditions(&k, "PRE", &eq.preconditions); tq += emit_conditions(&k, "POST", &eq.postconditions); } diff --git a/crates/aprender-present-cli/Cargo.toml b/crates/aprender-present-cli/Cargo.toml index f66f0f45ab..9249c0e6f6 100644 --- a/crates/aprender-present-cli/Cargo.toml +++ b/crates/aprender-present-cli/Cargo.toml @@ -22,7 +22,7 @@ tiny_http = "0.12" tungstenite = { version = "0.26", optional = true } [build-dependencies] -provable-contracts = { workspace = true } # #4369: build_helper::env_key, the one CONTRACT_* key builder +aprender-contracts-key = { workspace = true } # #4369, #5909: the one CONTRACT_* key builder (no engine dependency) aprender-build-sha = { workspace = true } # #4219: APR_GIT_SHA for --version serde = { version = "1", features = ["derive"] } serde-saphyr = { workspace = true } diff --git a/crates/aprender-present-cli/build.rs b/crates/aprender-present-cli/build.rs index cf8320e713..b5f8c3f8ea 100644 --- a/crates/aprender-present-cli/build.rs +++ b/crates/aprender-present-cli/build.rs @@ -49,10 +49,8 @@ fn main() { let total = bindings.bindings.len() as u32; for b in &bindings.bindings { - let var = provable_contracts::build_helper::env_key( - b.contract.trim_end_matches(".yaml"), - &b.equation, - ); + let var = + aprender_contracts_key::env_key(b.contract.trim_end_matches(".yaml"), &b.equation); println!("cargo:rustc-env={var}={}", b.status); if b.status == "implemented" { implemented += 1; diff --git a/crates/aprender-present-core/Cargo.toml b/crates/aprender-present-core/Cargo.toml index bcd37afbe3..f696474475 100644 --- a/crates/aprender-present-core/Cargo.toml +++ b/crates/aprender-present-core/Cargo.toml @@ -23,7 +23,7 @@ serde_json = { workspace = true } provable-contracts-macros = { workspace = true } [build-dependencies] -provable-contracts = { workspace = true } # #4369: build_helper::env_key, the one CONTRACT_* key builder +aprender-contracts-key = { workspace = true } # #4369, #5909: the one CONTRACT_* key builder (no engine dependency) serde = { workspace = true } serde-saphyr = { workspace = true } diff --git a/crates/aprender-present-core/build.rs b/crates/aprender-present-core/build.rs index e86c6773da..467ba3996e 100644 --- a/crates/aprender-present-core/build.rs +++ b/crates/aprender-present-core/build.rs @@ -84,7 +84,7 @@ fn emit_contract_file_pre_post(path: &PathBuf, total_pre: &mut usize, total_post return; }; for (eq_name, eq) in &parsed.equations { - let key = provable_contracts::build_helper::env_key(&stem, eq_name); + let key = aprender_contracts_key::env_key(&stem, eq_name); emit_pre_post_lists(&key, eq, total_pre, total_post); } } @@ -178,7 +178,7 @@ fn emit_binding_counts_and_vars(bf: &BindingFile) { } fn env_var_name(contract: &str, equation: &str) -> String { - provable_contracts::build_helper::env_key( + aprender_contracts_key::env_key( contract.trim_end_matches(".yaml").trim_end_matches(".yml"), equation, ) diff --git a/crates/aprender-rag/Cargo.toml b/crates/aprender-rag/Cargo.toml index f2f4ff3900..b1838638e8 100644 --- a/crates/aprender-rag/Cargo.toml +++ b/crates/aprender-rag/Cargo.toml @@ -72,7 +72,7 @@ sha2 = { version = "0.10", optional = true } rand = { version = "0.9", optional = true } [build-dependencies] -provable-contracts = { workspace = true } # #4369: build_helper::env_key, the one CONTRACT_* key builder +aprender-contracts-key = { workspace = true } # #4369, #5909: the one CONTRACT_* key builder (no engine dependency) serde = { version = "1", features = ["derive"] } serde-saphyr = { workspace = true } diff --git a/crates/aprender-rag/build.rs b/crates/aprender-rag/build.rs index cbf56d77fe..df297328bc 100644 --- a/crates/aprender-rag/build.rs +++ b/crates/aprender-rag/build.rs @@ -46,10 +46,8 @@ fn main() { let total = bindings.bindings.len() as u32; for b in &bindings.bindings { - let var = provable_contracts::build_helper::env_key( - b.contract.trim_end_matches(".yaml"), - &b.equation, - ); + let var = + aprender_contracts_key::env_key(b.contract.trim_end_matches(".yaml"), &b.equation); println!("cargo:rustc-env={var}={}", b.status); if b.status == "implemented" { implemented += 1; diff --git a/crates/aprender-serve/Cargo.toml b/crates/aprender-serve/Cargo.toml index 64d48d0846..989bcc27b0 100644 --- a/crates/aprender-serve/Cargo.toml +++ b/crates/aprender-serve/Cargo.toml @@ -176,7 +176,7 @@ libc = "0.2" uuid = { version = "1", features = ["v4", "serde", "js"] } [build-dependencies] -provable-contracts = { workspace = true } # #4369: build_helper::env_key, the one CONTRACT_* key builder +aprender-contracts-key = { workspace = true } # #4369, #5909: the one CONTRACT_* key builder (no engine dependency) # Parsing provable-contracts binding.yaml for CONTRACT_* env vars (build.rs) serde = { version = "1", features = ["derive"] } serde-saphyr = { workspace = true } diff --git a/crates/aprender-serve/build.rs b/crates/aprender-serve/build.rs index ce96a7518a..5505d5f80b 100644 --- a/crates/aprender-serve/build.rs +++ b/crates/aprender-serve/build.rs @@ -44,7 +44,7 @@ struct Binding { /// /// `"softmax-kernel-v1.yaml"` + `"softmax"` → `"CONTRACT_SOFTMAX_KERNEL_V1_SOFTMAX"` fn env_var_name(contract: &str, equation: &str) -> String { - provable_contracts::build_helper::env_key( + aprender_contracts_key::env_key( contract.trim_end_matches(".yaml").trim_end_matches(".yml"), equation, ) @@ -884,7 +884,7 @@ fn emit_contract_assertions() { continue; }; for (eq, e) in &y.equations { - let k = provable_contracts::build_helper::env_key(stem, eq); + let k = aprender_contracts_key::env_key(stem, eq); if !e.preconditions.is_empty() { println!("cargo:rustc-env={k}_PRE_COUNT={}", e.preconditions.len()); for (i, v) in e.preconditions.iter().enumerate() { diff --git a/crates/aprender-simulate/Cargo.toml b/crates/aprender-simulate/Cargo.toml index e5ff4de6bf..858d269d45 100644 --- a/crates/aprender-simulate/Cargo.toml +++ b/crates/aprender-simulate/Cargo.toml @@ -94,7 +94,7 @@ provable-contracts-macros = { workspace = true } # Code gated behind #[cfg(feature = "z3-proofs")] [build-dependencies] -provable-contracts = { workspace = true } # #4369: build_helper::env_key, the one CONTRACT_* key builder +aprender-contracts-key = { workspace = true } # #4369, #5909: the one CONTRACT_* key builder (no engine dependency) aprender-build-sha = { workspace = true } # #4219: APR_GIT_SHA for --version serde = { version = "1.0", features = ["derive"] } serde-saphyr = { workspace = true } # #5208: build.rs reads contract YAML through saphyr, not unsafe-libyaml diff --git a/crates/aprender-simulate/build.rs b/crates/aprender-simulate/build.rs index cb4d91ca06..f75b3d022f 100644 --- a/crates/aprender-simulate/build.rs +++ b/crates/aprender-simulate/build.rs @@ -120,7 +120,7 @@ fn emit_contract_file(path: &Path, total_pre: &mut usize, total_post: &mut usize return; }; for (eq_name, equation) in &contract.equations { - let key = provable_contracts::build_helper::env_key(stem, eq_name); + let key = aprender_contracts_key::env_key(stem, eq_name); emit_pre_post(&key, equation, total_pre, total_post); } } @@ -185,10 +185,8 @@ fn enforce_provable_binding() { fn emit_binding_vars(bf: &BindingFile) -> Vec { let mut gaps = Vec::new(); for b in &bf.bindings { - let var = provable_contracts::build_helper::env_key( - b.contract.trim_end_matches(".yaml"), - &b.equation, - ); + let var = + aprender_contracts_key::env_key(b.contract.trim_end_matches(".yaml"), &b.equation); println!("cargo:rustc-env={var}={}", b.status); if b.status != "implemented" { gaps.push(var); diff --git a/crates/aprender-train/Cargo.toml b/crates/aprender-train/Cargo.toml index ac52f7d28d..dc0f9e5514 100644 --- a/crates/aprender-train/Cargo.toml +++ b/crates/aprender-train/Cargo.toml @@ -135,7 +135,7 @@ zip = { version = "9.0", default-features = false, features = ["deflate"] } # R alimentar = { workspace = true, optional = true } # Dataset loading with parquet/arrow support (gated behind parquet feature) [build-dependencies] -provable-contracts = { workspace = true } # #4369: build_helper::env_key, the one CONTRACT_* key builder +aprender-contracts-key = { workspace = true } # #4369, #5909: the one CONTRACT_* key builder (no engine dependency) serde = { version = "1", features = ["derive"] } serde_yaml_ng = "0.10" diff --git a/crates/aprender-train/build.rs b/crates/aprender-train/build.rs index 9fc0b039c6..eeb44eba68 100644 --- a/crates/aprender-train/build.rs +++ b/crates/aprender-train/build.rs @@ -39,7 +39,7 @@ struct Binding { /// /// `"learning-rate-schedules-v1.yaml"` + `"cosine_warmup"` → `"CONTRACT_LEARNING_RATE_SCHEDULES_V1_COSINE_WARMUP"` fn env_var_name(contract: &str, equation: &str) -> String { - provable_contracts::build_helper::env_key( + aprender_contracts_key::env_key( contract.trim_end_matches(".yaml").trim_end_matches(".yml"), equation, ) @@ -260,7 +260,7 @@ fn emit_contract_file(path: &Path, total_pre: &mut usize, total_post: &mut usize return; }; for (eq_name, eq) in &parsed.equations { - let key = provable_contracts::build_helper::env_key(&stem, eq_name); + let key = aprender_contracts_key::env_key(&stem, eq_name); emit_pre_post(&key, eq, total_pre, total_post); } } diff --git a/crates/aprender-viz-ttop/Cargo.toml b/crates/aprender-viz-ttop/Cargo.toml index 077014a189..d96ef95f07 100644 --- a/crates/aprender-viz-ttop/Cargo.toml +++ b/crates/aprender-viz-ttop/Cargo.toml @@ -38,7 +38,7 @@ thiserror = "2.0" anyhow = "1.0" [build-dependencies] -provable-contracts = { path = "../aprender-contracts", package = "aprender-contracts" } # #4369 (excluded crate: no workspace deps): build_helper::env_key, the one CONTRACT_* key builder +aprender-contracts-key = { path = "../aprender-contracts-key" } # #4369, #5909 (excluded crate: no workspace deps): the one CONTRACT_* key builder serde = { version = "1.0", features = ["derive"] } serde-saphyr = { workspace = true } diff --git a/crates/aprender-viz-ttop/build.rs b/crates/aprender-viz-ttop/build.rs index d59e53abdb..f79fb9fca5 100644 --- a/crates/aprender-viz-ttop/build.rs +++ b/crates/aprender-viz-ttop/build.rs @@ -34,7 +34,7 @@ fn process_contract(path: &std::path::Path) -> (usize, usize) { let (mut pre, mut post) = (0, 0); for (name, eq) in &yaml.equations { - let key = provable_contracts::build_helper::env_key(&stem, name); + let key = aprender_contracts_key::env_key(&stem, name); if !eq.preconditions.is_empty() { println!("cargo:rustc-env={key}_PRE_COUNT={}", eq.preconditions.len()); pre += eq.preconditions.len(); diff --git a/scripts/cascade-publish.sh b/scripts/cascade-publish.sh index adb89423b2..f0e4851919 100755 --- a/scripts/cascade-publish.sh +++ b/scripts/cascade-publish.sh @@ -32,7 +32,7 @@ REPO_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) # Tier definitions per SPEC-HF-PUBLISH-001 § crates.io release cascade. declare -A TIERS -TIERS[1]="aprender-update apr-format aprender-build-sha aprender-contracts-macros aprender-quant aprender-gemm-codegen aprender-sparse aprender-solve aprender-rand aprender-fft aprender-image aprender-tensor aprender-cupti" +TIERS[1]="aprender-update apr-format aprender-build-sha aprender-contracts-macros aprender-contracts-key aprender-quant aprender-gemm-codegen aprender-sparse aprender-solve aprender-rand aprender-fft aprender-image aprender-tensor aprender-cupti" TIERS[2]="aprender-contracts aprender-core aprender-profile-core aprender-graph aprender-contrastive-data" TIERS[3]="aprender-profile" TIERS[4]="aprender-gpu" diff --git a/scripts/release/publish-order.txt b/scripts/release/publish-order.txt index 33751e194b..8bab042ce2 100644 --- a/scripts/release/publish-order.txt +++ b/scripts/release/publish-order.txt @@ -3,6 +3,7 @@ aprender-update apr-format aprender-common aprender-contracts-macros +aprender-contracts-key aprender-cupti aprender-data aprender-fft From 629d12307be1b298a1996f92910318306f1b9a18 Mon Sep 17 00:00:00 2001 From: t Date: Sun, 25 Oct 2026 08:56:32 +0100 Subject: [PATCH 4/4] build(contracts): key crate dependency via workspace = true; entry states why env_key stays in both crates (Refs #5909) PMAT-Ticket: PMAT-5909 Co-Authored-By: Claude Sonnet 5.5 --- crates/aprender-contracts/Cargo.toml | 2 +- docs/roadmaps/entries/PMAT-5909.yaml | 2 +- docs/roadmaps/roadmap.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/aprender-contracts/Cargo.toml b/crates/aprender-contracts/Cargo.toml index 85fcf2fdc1..f5a17cbb41 100644 --- a/crates/aprender-contracts/Cargo.toml +++ b/crates/aprender-contracts/Cargo.toml @@ -49,7 +49,7 @@ criterion = { version = "0.5", features = ["html_reports"] } # (no aprender dependency) → dev-dep introduces no cycle. Used only in tests. half = { workspace = true } # The shared key builder, dev-only: a normal or build dependency would add a unit to the pv build (12-unit budget, ci/sections.yml m5). #5909 -aprender-contracts-key = { path = "../aprender-contracts-key", version = "0.71.3" } +aprender-contracts-key = { workspace = true } [[bench]] name = "benchmarks" diff --git a/docs/roadmaps/entries/PMAT-5909.yaml b/docs/roadmaps/entries/PMAT-5909.yaml index 2c550c0768..da1492db81 100644 --- a/docs/roadmaps/entries/PMAT-5909.yaml +++ b/docs/roadmaps/entries/PMAT-5909.yaml @@ -19,5 +19,5 @@ labels: - kind:code notes: |- - Scope taken from #6294 (commit 1, PMAT-5909; issue #5909: aprender-contracts is 24 commits in 30 days and dirties 47 of 85 crates). #6294 is split by quorum triage-quorum-tickets-6294-6309-0718Z into one PR per ticket; this entry lets w5032 cut this piece. + Scope taken from #6294 (commit 1, PMAT-5909; issue #5909: aprender-contracts is 24 commits in 30 days and dirties 47 of 85 crates). #6294 is split by quorum triage-quorum-tickets-6294-6309-0718Z into one PR per ticket; this entry lets w5032 cut this piece. Why env_key stays in both crates: aprender-contracts cannot build-depend on or include!() a file outside its own package (crates.io packaging, and a normal dep adds a pv build unit past the 12-unit budget), so it keeps src/env_key.rs and the key crate is a dev-dependency (workspace = true); the test shared_key_crate_agrees_with_env_key_and_the_macro fails if the two copies drift. epic: null diff --git a/docs/roadmaps/roadmap.yaml b/docs/roadmaps/roadmap.yaml index 571b77a054..638faa95de 100644 --- a/docs/roadmaps/roadmap.yaml +++ b/docs/roadmaps/roadmap.yaml @@ -25616,7 +25616,7 @@ Not done, pending the ruling: moving the 31 fixture files to an obviously synthe labels: - kind:code notes: |- - Scope taken from #6294 (commit 1, PMAT-5909; issue #5909: aprender-contracts is 24 commits in 30 days and dirties 47 of 85 crates). #6294 is split by quorum triage-quorum-tickets-6294-6309-0718Z into one PR per ticket; this entry lets w5032 cut this piece. + Scope taken from #6294 (commit 1, PMAT-5909; issue #5909: aprender-contracts is 24 commits in 30 days and dirties 47 of 85 crates). #6294 is split by quorum triage-quorum-tickets-6294-6309-0718Z into one PR per ticket; this entry lets w5032 cut this piece. Why env_key stays in both crates: aprender-contracts cannot build-depend on or include!() a file outside its own package (crates.io packaging, and a normal dep adds a pv build unit past the 12-unit budget), so it keeps src/env_key.rs and the key crate is a dev-dependency (workspace = true); the test shared_key_crate_agrees_with_env_key_and_the_macro fails if the two copies drift. epic: null - id: PMAT-5914 github_issue: 5914