diff --git a/Cargo.lock b/Cargo.lock index 5d45f73d89..ea13d1f29c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -265,6 +265,7 @@ dependencies = [ "aprender-present-core", "aprender-present-terminal", "aprender-profile", + "aprender-quant", "aprender-rag-cli", "aprender-registry", "aprender-serve", diff --git a/crates/apr-cli/Cargo.toml b/crates/apr-cli/Cargo.toml index 1b66c7aad7..f92636ca7f 100644 --- a/crates/apr-cli/Cargo.toml +++ b/crates/apr-cli/Cargo.toml @@ -153,6 +153,10 @@ realizar = { workspace = true, optional = true } # 2026-04-05 PMAT-507: bumped 0.16.0→0.17 to match aprender root Cargo.toml (was diamond dep) trueno = { workspace = true, optional = true } +# The ggml type table (`GgmlType`: ids, names, block sizes), in-tree as crates/aprender-quant. +# Not optional: `apr hex` and `apr validate-manifest` name GGUF dtypes in every build (#3662). +trueno-quant = { workspace = true } + # Async runtime for server tokio = { version = "1", features = ["rt-multi-thread", "macros", "signal", "sync"], optional = true } diff --git a/crates/apr-cli/src/commands/hex_options_detect.rs b/crates/apr-cli/src/commands/hex_options_detect.rs index cf7c1b8ae4..4e5b14283b 100644 --- a/crates/apr-cli/src/commands/hex_options_detect.rs +++ b/crates/apr-cli/src/commands/hex_options_detect.rs @@ -140,6 +140,20 @@ assert_eq!(ggml_dtype_name(255), "Unknown"); } + /// #3662: the hand-typed table knew 11 ids, so a K-quant below Q4_K, every IQ + /// type and BF16 printed "Unknown" in `apr hex`. + #[test] + fn test_ggml_dtype_name_names_every_family() { + assert_eq!(ggml_dtype_name(10), "Q2_K"); + assert_eq!(ggml_dtype_name(16), "IQ2_XXS"); + assert_eq!(ggml_dtype_name(23), "IQ4_XS"); + assert_eq!(ggml_dtype_name(30), "BF16"); + // Ids ggml removed (Q4_2, Q4_3) are not live types: same token as never-existed. + assert_eq!(ggml_dtype_name(4), "Unknown"); + assert_eq!(ggml_dtype_name(5), "Unknown"); + assert_eq!(ggml_dtype_name(999), "Unknown"); + } + // ======================================================================== // parse_hex_offset // ======================================================================== diff --git a/crates/apr-cli/src/commands/sliding_window_entropy.rs b/crates/apr-cli/src/commands/sliding_window_entropy.rs index 4b08f98b12..dd11331a58 100644 --- a/crates/apr-cli/src/commands/sliding_window_entropy.rs +++ b/crates/apr-cli/src/commands/sliding_window_entropy.rs @@ -291,22 +291,10 @@ fn f16_to_f32(h: u16) -> f32 { f32::from_bits((sign << 31) | (exp32 << 23) | mant32) } -/// GGML dtype name from u32 discriminant +/// GGML dtype name from u32 discriminant, read from the ggml type table rather than a +/// copy of it: the hand-typed copy knew 11 ids and printed "Unknown" for the rest (#3662). fn ggml_dtype_name(dtype: u32) -> &'static str { - match dtype { - 0 => "F32", - 1 => "F16", - 2 => "Q4_0", - 3 => "Q4_1", - 6 => "Q5_0", - 7 => "Q5_1", - 8 => "Q8_0", - 9 => "Q8_1", - 12 => "Q4_K", - 13 => "Q5_K", - 14 => "Q6_K", - _ => "Unknown", - } + trueno_quant::GgmlType::from_id(dtype).map_or("Unknown", trueno_quant::GgmlType::as_str) } /// Print an annotated hex field diff --git a/crates/apr-cli/src/commands/validate_manifest.rs b/crates/apr-cli/src/commands/validate_manifest.rs index 0ee0d81aa1..068192b2f4 100644 --- a/crates/apr-cli/src/commands/validate_manifest.rs +++ b/crates/apr-cli/src/commands/validate_manifest.rs @@ -789,39 +789,10 @@ fn expected_ggml_tensor_type(quant: &str) -> Option { } } +/// The ggml type table's name for `t`, or "UNKNOWN" for an id that is not a live type +/// (removed upstream, or never assigned). Not a hand-typed copy of the table (#3662). fn ggml_type_name(t: u32) -> &'static str { - match t { - 0 => "F32", - 1 => "F16", - 2 => "Q4_0", - 3 => "Q4_1", - 6 => "Q5_0", - 7 => "Q5_1", - 8 => "Q8_0", - 9 => "Q8_1", - 10 => "Q2_K", - 11 => "Q3_K", - 12 => "Q4_K", - 13 => "Q5_K", - 14 => "Q6_K", - 15 => "Q8_K", - 16 => "IQ2_XXS", - 17 => "IQ2_XS", - 18 => "IQ3_XXS", - 19 => "IQ1_S", - 20 => "IQ4_NL", - 21 => "IQ3_S", - 22 => "IQ2_S", - 23 => "IQ4_XS", - 24 => "I8", - 25 => "I16", - 26 => "I32", - 27 => "I64", - 28 => "F64", - 29 => "IQ1_M", - 30 => "BF16", - _ => "UNKNOWN", - } + trueno_quant::GgmlType::from_id(t).map_or("UNKNOWN", trueno_quant::GgmlType::as_str) } /// Pick the "predominant" quantization type from a tensor-type histogram. @@ -1699,6 +1670,20 @@ mod tests { assert_eq!(ggml_type_name(14), "Q6_K"); } + /// #3662: the names come from the ggml type table, not a copy of it. This table + /// was complete when it was hand-typed; the rows pin that the move kept it so, + /// and kept the "UNKNOWN" token for ids that are not live types. + #[test] + fn pm008_ggml_type_name_is_the_upstream_table() { + assert_eq!(ggml_type_name(10), "Q2_K"); + assert_eq!(ggml_type_name(16), "IQ2_XXS"); + assert_eq!(ggml_type_name(23), "IQ4_XS"); + assert_eq!(ggml_type_name(30), "BF16"); + assert_eq!(ggml_type_name(4), "UNKNOWN"); + assert_eq!(ggml_type_name(5), "UNKNOWN"); + assert_eq!(ggml_type_name(999), "UNKNOWN"); + } + #[test] fn pm008_predominant_prefers_non_float() { let mut h = HashMap::new(); diff --git a/crates/aprender-serve/src/api/model_source.rs b/crates/aprender-serve/src/api/model_source.rs index 1b93e38c5d..fee58973e3 100644 --- a/crates/aprender-serve/src/api/model_source.rs +++ b/crates/aprender-serve/src/api/model_source.rs @@ -201,27 +201,12 @@ fn read_magic(path: &Path) -> Option> { /// /// Derived from the qtype actually stored in the loaded tensors, which is the /// ground truth — `general.file_type` in GGUF metadata is advisory and is -/// known to go stale when a file is requantized. +/// known to go stale when a file is requantized. The names come from the ggml type +/// table; the hand-typed copy this replaced knew 15 ids and reported no quantization +/// at all for every IQ type (#3662). #[must_use] pub fn gguf_qtype_name(qtype: u32) -> Option<&'static str> { - Some(match qtype { - 0 => "F32", - 1 => "F16", - 2 => "Q4_0", - 3 => "Q4_1", - 6 => "Q5_0", - 7 => "Q5_1", - 8 => "Q8_0", - 9 => "Q8_1", - 10 => "Q2_K", - 11 => "Q3_K", - 12 => "Q4_K", - 13 => "Q5_K", - 14 => "Q6_K", - 15 => "Q8_K", - 30 => "BF16", - _ => return None, - }) + trueno_quant::GgmlType::from_id(qtype).map(trueno_quant::GgmlType::as_str) } #[cfg(test)] @@ -313,4 +298,17 @@ mod tests { // Unknown ids must not be reported as some plausible quantization. assert_eq!(gguf_qtype_name(9999), None); } + + /// #3662: the hand-typed table knew 15 ids, so every IQ quantization reported + /// no quantization at all. + #[test] + fn qtype_names_cover_every_live_family() { + assert_eq!(gguf_qtype_name(10), Some("Q2_K")); + assert_eq!(gguf_qtype_name(16), Some("IQ2_XXS")); + assert_eq!(gguf_qtype_name(23), Some("IQ4_XS")); + assert_eq!(gguf_qtype_name(30), Some("BF16")); + // Removed upstream (Q4_2, Q4_3): not a quantization anything can hold. + assert_eq!(gguf_qtype_name(4), None); + assert_eq!(gguf_qtype_name(5), None); + } } diff --git a/docs/audits/quorum-PMAT-3662.json b/docs/audits/quorum-PMAT-3662.json new file mode 100644 index 0000000000..091ec92905 --- /dev/null +++ b/docs/audits/quorum-PMAT-3662.json @@ -0,0 +1,205 @@ +{ + "ticket": "PMAT-3662", + "base": "origin/main", + "base_resolved": "origin/main", + "base_note": "no origin/origin/main exists; judged against the local ref", + "head": "6b04f66a82ef40f9349d88d12faf8fe289b77866", + "diff_sha256": "4f3cb2d4adf71ae1a404f78110835ee97073997800c89a181b0e98ec139a5160", + "width": 3, + "executor": "agy", + "prompt_mode": "inline", + "prompt_bytes": 19429, + "author": { + "model": "claude-opus-5", + "family": "claude", + "source": "flag" + }, + "agreed": true, + "lanes": [ + { + "lane": 1, + "status": "SUCCESS", + "verdict": "PASS", + "summary": "The diff correctly addresses all four acceptance criteria of PMAT-3662.\n\n1. It replaces the hand-typed `match` arms in all three sites (`sliding_window_entropy.rs`, `validate_manifest.rs`, and `model_source.rs`) with `trueno_quant::GgmlType::from_id(...).map_or(...)` or `.map(...)`, as requested.\n2. It adds a new test per site that feeds ids 10 (Q2_K), 16 (IQ2_XXS), 23 (IQ4_XS), and 30 (BF16), resolving correctly to the upstream names.\n3. Unknown ids (e.g. 4, 5, 999) are explicitly tested and continue to print each site's existing unknown token (`\"Unknown\"`, `\"UNKNOWN\"`, or `None`), maintaining stability.\n4. `apr-cli`'s `Cargo.toml` properly adds the workspace dependency `trueno-quant = { workspace = true }`. As noted in the roadmap facts, `aprender-serve` already compiles correctly and thus its existing dependencies suffice. No claims from the ticket are weakened or missing.", + "findings": [], + "raw_bytes": 3954, + "err_bytes": 0, + "envelope_status": "SUCCESS", + "verdict_source": "structured_output", + "grounding_check": "parity", + "model": "gemini-3.1-pro-high", + "model_measured": "gemini-3.1-pro-high", + "model_source": "measured", + "family": "gemini" + }, + { + "lane": 2, + "status": "SUCCESS", + "verdict": "PASS", + "summary": "The diff implements all four acceptance criteria of PMAT-3662 exactly as specified.\n\n1. It replaces the hand-typed match arms in `sliding_window_entropy.rs`, `validate_manifest.rs`, and `model_source.rs` with `trueno_quant::GgmlType::from_id(id).map_or(..., GgmlType::as_str)` or equivalent.\n2. It adds a test to each site that feeds the required ids `10`, `16`, `23`, and `30` and checks they map to their correct upstream names (`Q2_K`, `IQ2_XXS`, `IQ4_XS`, `BF16`).\n3. Unknown ids `4` and `5` (and `999`/`9999` either newly added or via pre-existing tests) return the site's specific unknown tokens (`\"Unknown\"`, `\"UNKNOWN\"`, and `None` respectively).\n4. `apr-cli/Cargo.toml` correctly adds `trueno-quant = { workspace = true }` as a dependency.", + "findings": [], + "raw_bytes": 3670, + "err_bytes": 0, + "envelope_status": "SUCCESS", + "verdict_source": "structured_output", + "grounding_check": "parity", + "model": "gemini-3.1-pro-low", + "model_measured": "gemini-3.1-pro-low", + "model_source": "measured", + "family": "gemini" + }, + { + "lane": 3, + "status": "SUCCESS", + "verdict": "PASS", + "summary": "As Lane 3 of 3 independent reviewers, I have reviewed the diff against Ticket PMAT-3662. All four acceptance criteria are fully met:\n\n1. Every non-example id->name mapping in `apr-cli` (`sliding_window_entropy.rs:297`, `validate_manifest.rs:795`) and `aprender-serve` (`model_source.rs:209`) routes through `trueno_quant::GgmlType::from_id(id)`.\n2. Tests covering IDs 10 (Q2_K), 16 (IQ2_XXS), 23 (IQ4_XS), 30 (BF16), and unknown IDs have been added for all three sites (`hex_options_detect.rs:145`, `validate_manifest.rs:1676`, `model_source.rs:304`).\n3. Unknown IDs maintain site-specific unknown tokens (\"Unknown\", \"UNKNOWN\", None).\n4. `apr-cli` workspace dependency on `trueno-quant` is added to `Cargo.toml:158` and reflected in `Cargo.lock:268`.\n\nNo refutations, weakened gates, or out-of-scope changes were found. Verdict: PASS.", + "findings": [ + { + "claim": "apr-cli Cargo.toml adds dependency trueno-quant = { workspace = true }, satisfying acceptance criterion 4.", + "file": "crates/apr-cli/Cargo.toml", + "fix": "N/A", + "grounding": "cited", + "line": 158 + }, + { + "claim": "ggml_dtype_name in apr-cli/src/commands/sliding_window_entropy.rs is routed through trueno_quant::GgmlType::from_id(dtype).map_or(\"Unknown\", trueno_quant::GgmlType::as_str), preserving the \"Unknown\" fallback token.", + "file": "crates/apr-cli/src/commands/sliding_window_entropy.rs", + "fix": "N/A", + "grounding": "cited", + "line": 297 + }, + { + "claim": "test_ggml_dtype_name_names_every_family in apr-cli/src/commands/hex_options_detect.rs verifies IDs 10 (Q2_K), 16 (IQ2_XXS), 23 (IQ4_XS), 30 (BF16) and unknown IDs 4, 5, 999.", + "file": "crates/apr-cli/src/commands/hex_options_detect.rs", + "fix": "N/A", + "grounding": "cited", + "line": 145 + }, + { + "claim": "ggml_type_name in apr-cli/src/commands/validate_manifest.rs is routed through trueno_quant::GgmlType::from_id(t).map_or(\"UNKNOWN\", trueno_quant::GgmlType::as_str), preserving the \"UNKNOWN\" fallback token.", + "file": "crates/apr-cli/src/commands/validate_manifest.rs", + "fix": "N/A", + "grounding": "cited", + "line": 795 + }, + { + "claim": "pm008_ggml_type_name_is_the_upstream_table in apr-cli/src/commands/validate_manifest.rs verifies IDs 10, 16, 23, 30 and unknown IDs 4, 5, 999.", + "file": "crates/apr-cli/src/commands/validate_manifest.rs", + "fix": "N/A", + "grounding": "cited", + "line": 1676 + }, + { + "claim": "gguf_qtype_name in aprender-serve/src/api/model_source.rs is routed through trueno_quant::GgmlType::from_id(qtype).map(trueno_quant::GgmlType::as_str), preserving the Option return type.", + "file": "crates/aprender-serve/src/api/model_source.rs", + "fix": "N/A", + "grounding": "cited", + "line": 209 + }, + { + "claim": "qtype_names_cover_every_live_family in aprender-serve/src/api/model_source.rs verifies IDs 10, 16, 23, 30 and unknown IDs 4, 5.", + "file": "crates/aprender-serve/src/api/model_source.rs", + "fix": "N/A", + "grounding": "cited", + "line": 304 + } + ], + "raw_bytes": 7916, + "err_bytes": 0, + "envelope_status": "SUCCESS", + "verdict_source": "structured_output", + "grounding_check": "parity", + "model": "gemini-3.6-flash-high", + "model_measured": "gemini-3.6-flash-high", + "model_source": "measured", + "family": "gemini" + } + ], + "dissent": [], + "dedup": [ + { + "file": "crates/apr-cli/Cargo.toml", + "line": 158, + "lanes_agreeing": [ + 3 + ], + "claims": [ + "apr-cli Cargo.toml adds dependency trueno-quant = { workspace = true }, satisfying acceptance criterion 4." + ] + }, + { + "file": "crates/apr-cli/src/commands/hex_options_detect.rs", + "line": 145, + "lanes_agreeing": [ + 3 + ], + "claims": [ + "test_ggml_dtype_name_names_every_family in apr-cli/src/commands/hex_options_detect.rs verifies IDs 10 (Q2_K), 16 (IQ2_XXS), 23 (IQ4_XS), 30 (BF16) and unknown IDs 4, 5, 999." + ] + }, + { + "file": "crates/apr-cli/src/commands/sliding_window_entropy.rs", + "line": 297, + "lanes_agreeing": [ + 3 + ], + "claims": [ + "ggml_dtype_name in apr-cli/src/commands/sliding_window_entropy.rs is routed through trueno_quant::GgmlType::from_id(dtype).map_or(\"Unknown\", trueno_quant::GgmlType::as_str), preserving the \"Unknown\" fallback token." + ] + }, + { + "file": "crates/apr-cli/src/commands/validate_manifest.rs", + "line": 795, + "lanes_agreeing": [ + 3 + ], + "claims": [ + "ggml_type_name in apr-cli/src/commands/validate_manifest.rs is routed through trueno_quant::GgmlType::from_id(t).map_or(\"UNKNOWN\", trueno_quant::GgmlType::as_str), preserving the \"UNKNOWN\" fallback token." + ] + }, + { + "file": "crates/apr-cli/src/commands/validate_manifest.rs", + "line": 1676, + "lanes_agreeing": [ + 3 + ], + "claims": [ + "pm008_ggml_type_name_is_the_upstream_table in apr-cli/src/commands/validate_manifest.rs verifies IDs 10, 16, 23, 30 and unknown IDs 4, 5, 999." + ] + }, + { + "file": "crates/aprender-serve/src/api/model_source.rs", + "line": 209, + "lanes_agreeing": [ + 3 + ], + "claims": [ + "gguf_qtype_name in aprender-serve/src/api/model_source.rs is routed through trueno_quant::GgmlType::from_id(qtype).map(trueno_quant::GgmlType::as_str), preserving the Option return type." + ] + }, + { + "file": "crates/aprender-serve/src/api/model_source.rs", + "line": 304, + "lanes_agreeing": [ + 3 + ], + "claims": [ + "qtype_names_cover_every_live_family in aprender-serve/src/api/model_source.rs verifies IDs 10, 16, 23, 30 and unknown IDs 4, 5." + ] + } + ], + "uncovered": [], + "coverage_source": "lanes", + "partial": false, + "partial_reasons": [], + "auto_merge": { + "checked": true, + "was_armed": false, + "disarmed": false, + "note": "auto-merge not armed" + }, + "lint": { + "ok": true, + "output": "receipt complete: kind=artifact lanes=3 author=claude-opus-5/claude" + } +} diff --git a/docs/roadmaps/entries/PMAT-3662.yaml b/docs/roadmaps/entries/PMAT-3662.yaml new file mode 100644 index 0000000000..056c9e5fb6 --- /dev/null +++ b/docs/roadmaps/entries/PMAT-3662.yaml @@ -0,0 +1,23 @@ +- id: PMAT-3662 + github_issue: 3662 + item_type: task + title: 'Hand-typed ggml id→name tables outside aprender-core: sliding_window_entropy.rs, validate_manifest.rs, aprender-serve model_source.rs name 11 of 35 live types; route through trueno_quant::GgmlType' + status: in_progress + priority: medium + assigned_to: aprender-62 + created: 2026-09-21T06:40:00Z + updated: 2026-09-21T06:40:00Z + spec: null + acceptance_criteria: + - 'Issue #3662 done_when 1, verbatim: "Every non-example id→name mapping in `apr-cli` and `aprender-serve` resolves through `trueno_quant::GgmlType::from_id(id).map_or(, GgmlType::as_str)`, or through one shared helper that does. No `12 => "Q4_K"`-shaped match arm remains outside `aprender-quant` in those two crates'' `src/`."' + - 'Issue #3662 done_when 2, verbatim (as amended by the filer 2026-09-21 after measuring): "A test per site feeds ids 10 (Q2_K), 16 (IQ2_XXS), 23 (IQ4_XS) and 30 (BF16) and gets the upstream names. It is RED on today''s tables where they are incomplete (sliding_window_entropy.rs, model_source.rs). validate_manifest.rs was complete when measured (amended 2026-09-21 by the filer), so its row is a parity row and passes before and after."' + - 'Issue #3662 done_when 3, verbatim: "Unknown ids (e.g. 4, 5, 999) still print the site''s existing unknown token, so output stays stable for ids ggml removed."' + - 'Issue #3662 done_when 4, verbatim: "`apr-cli` depends on the quant crate via `{ workspace = true }` (no crates.io copy)."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Found by aprender-7a (sliding_window_entropy.rs:295); the other two sites found by aprender-62 at origin/main c0ab699b0 with a scan of crates/apr-cli/src and crates/aprender-serve/src for ` => "Q4_K"`-shaped arms, which returns exactly three: apr-cli commands/sliding_window_entropy.rs `ggml_dtype_name` (unknown token "Unknown"; knows 11 ids), apr-cli commands/validate_manifest.rs `ggml_type_name` (unknown token "UNKNOWN"; knows ids 0-3,6-30, so it is complete today but hand-typed), aprender-serve api/model_source.rs `gguf_qtype_name` (returns None; knows 15 ids, so every IQ*, I8-I64 and F64 is None). "RED on today''s tables" is per site. validate_manifest.rs already names 10/16/23/30 correctly, so its row (ids 10/16/23/30 plus unknown ids 4/5/999, the same ids as the other two sites) is a parity row and is not expected to be RED. The two tables that are wrong today (sliding_window_entropy, model_source) carry the RED rows. validate_manifest.rs''s reverse name→id parser (`"iq4_xs" => Some(23)`) has case-insensitive aliases ("bfloat16") and is not an id→name mapping. It is out of scope and stays. Examples under crates/aprender-serve/examples/ are out of scope per the issue. + + Facts a reviewer needs, each checked at the PR head (round 1 of the quorum misread all three). (1) WHERE sliding_window_entropy.rs IS TESTED: it is not a module. crates/apr-cli/src/commands/hex.rs:442 is `include!("sliding_window_entropy.rs")`, and hex.rs:444 includes hex_06.rs, whose :11 is `include!("hex_options_detect.rs")`. So `ggml_dtype_name` and its tests share one module, `commands::hex`. The pre-existing tests for this function (test_ggml_dtype_name_known/_unknown) already live in hex_options_detect.rs, and the new test_ggml_dtype_name_names_every_family sits beside them. It ran as commands::hex::tests::test_ggml_dtype_name_names_every_family: RED on the old table (left "Unknown", right "Q2_K"), GREEN after. (2) THE CRATE NAME: the workspace dependency is `trueno-quant = { path = "crates/aprender-quant", ..., package = "aprender-quant" }` (root Cargo.toml:262), and Cargo.lock records PACKAGE names. So `aprender-quant` in apr-cli''s Cargo.lock dependency list is what cargo wrote for `trueno-quant = { workspace = true }`. It was generated by cargo, not hand-edited. (3) GgmlType IS EXPORTED: crates/aprender-quant/src/lib.rs has an unconditional `pub mod ggml_type;` and `pub use ggml_type::{GgmlFamily, GgmlType, ...}`. The type was added by #3581 AFTER the v0.68.2 tag (`git cat-file -e v0.68.2:crates/aprender-quant/src/ggml_type.rs` fails), so a tree at or before v0.68.2, or the crates.io aprender-quant 0.68.2, does not have it and fails with E0433. At the PR head, `cargo check -p aprender-serve` and `cargo check -p apr-cli` both exit 0. Verified at the PR head: cargo test -p aprender-serve --lib model_source 19 passed; cargo test -p apr-cli --lib -- commands::hex commands::validate_manifest 174 passed; clippy -D warnings clean on both crates.' diff --git a/docs/roadmaps/roadmap.yaml b/docs/roadmaps/roadmap.yaml index 84e48c530f..6aae26361a 100644 --- a/docs/roadmaps/roadmap.yaml +++ b/docs/roadmaps/roadmap.yaml @@ -19007,3 +19007,26 @@ roadmap: labels: - kind:code notes: 'ACCEPTANCE (hand-entered from issue #3629 done_when; minted on the PR branch so the AD-04 quorum can run -- pmat work status refuses a missing item). Done when: scripts/fleet_utilization.sh --selftest has no pipe into grep -q; a mutation that restores the pipe AND forces EPIPE (out padded to >64 KiB so the write cannot complete before grep exits) turns the self-test RED deterministically — the positive control for the race, in the PR body the 55-site count is in the PR body from the command that produced it, and a guard refuses a new site (check_guards_are_wired.sh names it; ratchet baseline committed) main''s guard-tree green on the merge commit without rerun ' +- id: PMAT-3662 + github_issue: 3662 + item_type: task + title: 'Hand-typed ggml id→name tables outside aprender-core: sliding_window_entropy.rs, validate_manifest.rs, aprender-serve model_source.rs name 11 of 35 live types; route through trueno_quant::GgmlType' + status: in_progress + priority: medium + assigned_to: aprender-62 + created: 2026-09-21T06:40:00Z + updated: 2026-09-21T06:40:00Z + spec: null + acceptance_criteria: + - 'Issue #3662 done_when 1, verbatim: "Every non-example id→name mapping in `apr-cli` and `aprender-serve` resolves through `trueno_quant::GgmlType::from_id(id).map_or(, GgmlType::as_str)`, or through one shared helper that does. No `12 => "Q4_K"`-shaped match arm remains outside `aprender-quant` in those two crates'' `src/`."' + - 'Issue #3662 done_when 2, verbatim (as amended by the filer 2026-09-21 after measuring): "A test per site feeds ids 10 (Q2_K), 16 (IQ2_XXS), 23 (IQ4_XS) and 30 (BF16) and gets the upstream names. It is RED on today''s tables where they are incomplete (sliding_window_entropy.rs, model_source.rs). validate_manifest.rs was complete when measured (amended 2026-09-21 by the filer), so its row is a parity row and passes before and after."' + - 'Issue #3662 done_when 3, verbatim: "Unknown ids (e.g. 4, 5, 999) still print the site''s existing unknown token, so output stays stable for ids ggml removed."' + - 'Issue #3662 done_when 4, verbatim: "`apr-cli` depends on the quant crate via `{ workspace = true }` (no crates.io copy)."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Found by aprender-7a (sliding_window_entropy.rs:295); the other two sites found by aprender-62 at origin/main c0ab699b0 with a scan of crates/apr-cli/src and crates/aprender-serve/src for ` => "Q4_K"`-shaped arms, which returns exactly three: apr-cli commands/sliding_window_entropy.rs `ggml_dtype_name` (unknown token "Unknown"; knows 11 ids), apr-cli commands/validate_manifest.rs `ggml_type_name` (unknown token "UNKNOWN"; knows ids 0-3,6-30, so it is complete today but hand-typed), aprender-serve api/model_source.rs `gguf_qtype_name` (returns None; knows 15 ids, so every IQ*, I8-I64 and F64 is None). "RED on today''s tables" is per site. validate_manifest.rs already names 10/16/23/30 correctly, so its row (ids 10/16/23/30 plus unknown ids 4/5/999, the same ids as the other two sites) is a parity row and is not expected to be RED. The two tables that are wrong today (sliding_window_entropy, model_source) carry the RED rows. validate_manifest.rs''s reverse name→id parser (`"iq4_xs" => Some(23)`) has case-insensitive aliases ("bfloat16") and is not an id→name mapping. It is out of scope and stays. Examples under crates/aprender-serve/examples/ are out of scope per the issue. + + Facts a reviewer needs, each checked at the PR head (round 1 of the quorum misread all three). (1) WHERE sliding_window_entropy.rs IS TESTED: it is not a module. crates/apr-cli/src/commands/hex.rs:442 is `include!("sliding_window_entropy.rs")`, and hex.rs:444 includes hex_06.rs, whose :11 is `include!("hex_options_detect.rs")`. So `ggml_dtype_name` and its tests share one module, `commands::hex`. The pre-existing tests for this function (test_ggml_dtype_name_known/_unknown) already live in hex_options_detect.rs, and the new test_ggml_dtype_name_names_every_family sits beside them. It ran as commands::hex::tests::test_ggml_dtype_name_names_every_family: RED on the old table (left "Unknown", right "Q2_K"), GREEN after. (2) THE CRATE NAME: the workspace dependency is `trueno-quant = { path = "crates/aprender-quant", ..., package = "aprender-quant" }` (root Cargo.toml:262), and Cargo.lock records PACKAGE names. So `aprender-quant` in apr-cli''s Cargo.lock dependency list is what cargo wrote for `trueno-quant = { workspace = true }`. It was generated by cargo, not hand-edited. (3) GgmlType IS EXPORTED: crates/aprender-quant/src/lib.rs has an unconditional `pub mod ggml_type;` and `pub use ggml_type::{GgmlFamily, GgmlType, ...}`. The type was added by #3581 AFTER the v0.68.2 tag (`git cat-file -e v0.68.2:crates/aprender-quant/src/ggml_type.rs` fails), so a tree at or before v0.68.2, or the crates.io aprender-quant 0.68.2, does not have it and fails with E0433. At the PR head, `cargo check -p aprender-serve` and `cargo check -p apr-cli` both exit 0. Verified at the PR head: cargo test -p aprender-serve --lib model_source 19 passed; cargo test -p apr-cli --lib -- commands::hex commands::validate_manifest 174 passed; clippy -D warnings clean on both crates.'