Preliminary version · Round 1 (11 repositories)

The numbers in this document — Kappa, filter precision, and per-category frequencies — come from a pilot labelling round still under review. They will be recalculated in the definitive round with two human annotators. Consult the final version before citing.

Methodological report · Empirical evidence trail

Issue mining for Stargazer v2

What 7,889 GitHub issues say about the cost of on-device LLM inference, and by exactly which criteria each number was produced.

Authors Luana Almeida · Tiago Bittencourt Collection 2026-09-30 Updated 2026-10-08 Target ICSE 2028 Base protocol Islam et al. (2019) Repository research-analysis-stargazer

§1Executive summary and maturity status

The study mines GitHub Issues from 11 repositories in the on-device inference ecosystem to measure what practitioners report when a model's execution cost surprises them. It exists to answer, with observed data rather than assumption, whether the cost predictor Stargazer v2 proposes solves a real problem, and how big that problem is.

Raw issues7,8893,600 queries · 11 repos · 2017–2026
After filter v26207.9% retention
Labelled sample60stratified, seed 2028
Confirmed27measured filter precision: 45%
Cohen's Kappa0.795Substantial · threshold was ≥ 0.61
Median surprise4.0×n = 81 issues with explicit magnitude

How to read this document: what is definitive and what is not

Every claim in the report carries one of these three seals. They are not decoration: they separate what can already go into the paper from what still depends on pending human work.

SealMeansWhere it appears
measuredDerived directly from the collected data, by a reproducible script, with no intervening human judgment.Funnel counts, collection provenance, discard statistics, backend lifts, magnitude of degradations.
preliminaryDepends on labels that exist, but were produced in a pilot round and will be replaced.Kappa of 0.795, precision of 45%, entry-point and category distribution over the confirmed set; M1–M3 pilot screening (86 included, Kappa of 0.731).
pendingThe instrument is built and the sample drawn, but no one has filled it in yet.Filter recall (audit of 45 discards), human round of M1–M3 screening of the 172 approved repositories.
Central caveat, stated before any result

The labelling round that produced the Kappa of 0.795 was not run by two independent humans. It was run by two annotator roles operated by an LLM, defined in .claude/skills/msr-avaliador-1 and msr-avaliador-2, each with a deliberately distinct decision rule (detail in §3.6).

Exact consequence: the Kappa measures agreement between two written decision rules, not between two human judgments. This has real value — it is a dry run that already exposed a serious pipeline defect (§5.2) and an ambiguity in the operational definition itself (§6.4) before spending hours of human labelling. But this is not the Kappa that goes into the paper. The definitive round (Tiago + Isaque/Breno, in parallel and without consultation) is pending, and every frequency derived from it must be recalculated.

The six conclusions the corpus supports today

  1. Memory is the cause; speed is the symptom. 64% of retained issues have Memory as the primary category, and latency/throughput appear 316 times as the secondary category of those same issues. A predictor that gets memory right solves most of the problem.
  2. The median surprise is a factor of 4. This is not a calibration error, it is a qualitative prediction failure. The accuracy bar required of Stargazer v2 is generous: what is at stake is "fits / doesn't fit".
  3. RQ2, as written, has a negative answer. Model × hardware does not concentrate problems (lifts between 0.54 and 1.54). Backend × platform does concentrate them (lifts up to 31.0). The RQ needs to be reformulated.
  4. The energy axis does not survive the filter, and that is different from not existing. Zero Energy issues in the retained set, but 77 discarded issues mention battery, energy, power, or thermal. The cause is the measurability criterion, not the source.
  5. The predictor's declarable reach is ~26%, not 69%. Labelling reversed the heuristic's estimate: the dominant slice is Toolchain (regression between versions, backend choice, scheduler decision), which no static predictor anticipates.
  6. n_ctx is a mandatory input feature. 40% of retained issues mention KV cache or context, and 90% of those are memory issues. Estimating from the weights file alone is insufficient by construction.

§2Framing: why MSR, and what it answers

The role of MSR within the paper

The Stargazer v2 bench experiments (llama.cpp on Linux laptop and Android, Qwen2.5 at three sizes, fixed vs. marginal cost separation, Roofline validation) measure cost. They do not say which costs matter in practice, nor how often practitioners misjudge them in advance. MSR occupies exactly that gap: it is the observational evidence that the problem exists outside the lab, and it is the source of the evaluation instances against which the predictor will be tested.

The claim the corpus needs to support is narrower and stronger than "people suffer from inference cost":

Weak claim, not what we are after

"Running an LLM on-device consumes a lot of memory and is slow." True, banal, and does not support a software-engineering paper.

Claim the corpus supports

"Execution cost is systematically unpredictable before execution, the prediction error has a median magnitude of 4×, and the ecosystem has already tried to solve it and failed in a documented way." This is searchable, quantifiable, and specific.

The three research questions and how each was instrumented

RQQuestionInstrument in the pipelineStatus
RQ1 What categories of resource problem are reported when running LLMs on-device? Column categoria_recurso ∈ {Memory, Latency, Energy, Temperature, Throughput, Other}, assigned by symptom regex and corrected during labelling. answered with a relevant negative result on the energy axis
RQ2 Which model × hardware × backend combinations generate the most problems? Triple extracted by regex over model name, SoC/platform, and backend; concentration test by lift over the marginal frequencies. negative as written, requires reformulation to backend × platform
RQ3 What is the impact of quantization parameters on reported execution cost? Fields quantizacao and metricas_numericas; terms GGUF, KV cache, context length in the search matrix. answered with a counter-intuitive finding (quantize the cache, not the weights)

Source: data/msr/keyword_matrix.md, section 6.1 (keyword → RQ map).

§3Methodology, stage by stage

The pipeline has seven stages. Each has a hand-written input artifact (the source of truth), a script that runs it, and a generated output that is never edited by hand. The rule is deliberate: if the number in the paper diverges from the number in the dataset, the divergence is a defect, not a wording detail.

#StageScriptSource of truth (hand-written)Generated output
0Repository selectionselect_repos.pyrepository_matrix.mdrepository_selection.md, repo_candidates.csv
1Miningmine_issues.pykeyword_matrix.mdissues_raw.jsonl, mining_provenance.json
2Quality filterfilter_issues.pyweights in VIOLATION_SIGNALSissues_filtered.jsonl, filter_stats.json, top_issues.md
3Samplingsample_for_annotation.pyseed 2028, quota per repositoryissues_sample_eval.csv
4Labellingsplit_for_annotators.py, merge_annotations.pyannotation/PROTOCOL.mdannotator_1.csv, annotator_2.csv
5Agreementcalculate_kappa.pyKappa threshold ≥ 0.61kappa_report.md, disagreements.csv
6Discard auditinverse_filter.pydeclared suspicion weightsdiscard_audit.md, audit_sample.csv
7Funnelbuild_funnel.pyn/afunnel_diagram.md, funnel_table.md

3.1 Repository selection: the funnel that comes before the funnel

The first version of the study mined 11 repositories chosen from knowledge of the ecosystem. The justification ("each one is a distinct entry point") is true, but it was built after the choice, which makes it a purposive sample with no declared population frame. Without a protocol, the answer to "how did you choose these repositories?" is "the ones we knew".

The protocol was then written and executed against the API. It declares the unit of analysis (a public GitHub repository), the frame (repositories that implement, package, or consume LLM inference on an end-user device), and what falls outside it by definition: training, datacenter serving, libraries with no on-device path, link collections.

Automatic criteria (verifiable via the API, no judgment)
A1 · A2
not a fork; not archived
A3
has_issues == true
A4
≥ 50 closed issues, funnel viability threshold
A5
≥ 20 issues updated in the last 12 months
A6
≥ 200 stars, relevance proxy
Manual criteria (require judgment)
M1
does the repository run or package LLM/ASR inference?
M2
is there a documented path to an end-user device?
M3
does the tracker receive execution-cost reports, not just build reports?

Only repositories with M1 and M2 true enter the study. M3 false is a declared caveat, not an exclusion — density of cost reports is a result, not a criterion.

Two criterion decisions worth recording, because they are corrections and not recalibrations

A5 measures tracker activity, not code activity. The initial operationalization used pushed_at, which counts commits. A repository that exists only to receive issues — the bug tracker of a closed-source product — has no commits. Since the study mines issues, the correct measure of activity is the tracker's. The change was motivated by an observed failure: lmstudio-ai/lmstudio-bug-tracker failed on pushed_at despite having 489 closed issues and an active tracker. The criterion was poorly operationalized, not poorly calibrated.

A6 is the most questionable of the six criteria. Stars favor Western, English-speaking projects. This is declared, and the protocol opens an explicit exception for repositories that fill an empty coverage cell.

Selection funnel as executed

StageCriterionRepositories
E0raw results from the 12 seed queries3,430
E1unique repositories3,175
E2A1 + A2 · not a fork, not archived3,075
E3A3 · issues enabled3,029
E4A6 · stars ≥ 200 (+0 by cell exception)508
E5A5 · tracker active in the last 12 months246
E6A4 · ≥ 50 closed issues172
E7manual screening M1–M3 human round pending0

Source: data/msr/repository_selection.md, generated on 2026-10-05. A6 runs before A5 and A4 because the latter cost API calls and, applied last, run over fewer candidates. The 172 approved are in annotation/repo_screening.csv; the blind screening protocol is in annotation/SCREENING_PROTOCOL.md.

E7 ran only as an LLM pilot: 86 included

To test stage 00 end to end before the human round, two LLM-operated evaluator roles filled in the two blind spreadsheets. Both included 86 of the 172, excluded 63, and disagreed on 23, still without a tiebreak. The pre-tiebreak Kappa was 0.717 on M1, 0.827 on M2, and 0.731 on the inclusion decision. The 86 are the list that has been under collection since 2026-10-07 (see the funnel page), but the pilot's provenance file prohibits citing these numbers in the paper. In the official funnel, E7 remains 0 until human screening.

Context signal: orders screening, excludes no one

A1–A6 measure popularity and activity and never ask whether the repository is about on-device inference cost. The context signal asks that question using the vocabulary of the keyword matrix, the same one stage 01 uses for mining. The two halves are measured in different units and are therefore reported separately:

  • 115 of 172 have at least one on-device cost issue in the tracker, by the matrix's 3 primary queries;
  • 5 of 172 mention, in their own name, description, or topics, a resource term and a device term.

Using it as a threshold would repeat A6's mistake: a single number eliminating the scarcest cohort. It only sets the order of the screening spreadsheet (tracker probe, then text, then issue volume).

Sensitivity of the A6 threshold
Stars ≥Pass A6ApprovedOf the 12
10066118412
20050817211
50031515111

"Approved" pass A1–A6; "Of the 12" counts the original repositories that remain approved. Multiplying the threshold by five (100 → 500 stars) changes the approved set by 33 repositories (184 → 151). Of the original 12, only lmstudio-bug-tracker depends on where the line falls.

A distinction that matters for the paper, and that the validation document states explicitly: the protocol was applied to the study's 12 repositories in a confirmatory way — it checked the list against the criteria after the fact. It did not generate the list. In the generative funnel, 11 of the 12 survive:

  • lmstudio-ai/lmstudio-bug-tracker fails A6 (155 stars). In the retroactive validation it enters through the cell exception, being the only papel:aplicativo (app-role) entry in the original list; in the generative funnel that cell already has 29 candidates, so the exception does not apply.
  • ROCm/ROCm survives under the name GitHub resolves it to today, ROCm/legacy-rocm-build (HTTP 301 redirect). Comparing only the declared names would mark it as failed. Under the new name, the pilot collection of the 86 obtained 304 issues, which points to the old name as the cause of the collection's HTTP 422 (§3.3).

The claim that is actually supported is therefore "the study's repositories satisfy declared quality criteria", not "the protocol selected these repositories". The generative funnel produces a different list: there are 161 approved candidates that the original list did not have, and the pilot screening included 75 of them.

Coverage grid: the 172 approved fill all 18 cells

The original list leaves cells empty: the retroactive validation (data/msr/repository_validation.md) flags 5 of 18 — plataforma:web · acelerador:qualcomm · acelerador:intel · acelerador:nvidia · acelerador:arm_cpu. Among the 172 approved, all 18 have at least one repository — for example 29 in papel:aplicativo, none of them dependent on the star exception, and 2 in acelerador:qualcomm.

These assignments are automatic suggestions, not triaged classification: the equivalent classifier at the issue level was wrong by almost a factor of three. The bias report (data/msr/selection_bias_report.md) uses these suggestions to test concentration in Apple: it drops on the accelerator axis (50% → 46%) and does not drop on the platform axis (33% → 44%). This is a finding to report, not a reason to adjust the queries until the number flips. Until human screening, every empty cell in the original list remains a threat to external validity to be declared.

3.2 Search strategy: no term enters without a reference backing it

The keyword matrix is the single source of truth for the search, and mine_issues.py reads the file: changing the queries there changes the collection. The property this matrix guarantees is the answer to the committee question "why exactly these keywords?" — each of the 26 has a line with a technical justification and a literature reference.

The vocabulary was derived through four rules, adapted from Islam et al. (2019)'s protocol for Deep Learning bugs to on-device inference cost:

  1. Seed from the symptom literature. Islam et al. derive the vocabulary from observable symptoms, not root-cause names, because the reporter describes what they saw, not the diagnosis. Hence "out of memory", OOM, slow, thermal throttl, and not "allocator memory pressure".
  2. Seed from the study object's metrics. Every Stargazer regression target (duration, energy, memory, throughput) needs a corresponding term, otherwise the evidence does not cover the variable the model predicts.
  3. Seed from the ecosystem's native jargon. Codabux et al. (2025) warn that MSR recall is dominated by adherence to the mined community's jargon, not the academic one. Hence tok/s (not just "throughput"), KV cache, GGUF, Q4_K_M.
  4. Precision filter by device context. Pure resource terms return massively server-side issues. Every Resource term is combined with at least one Device/Context term, the two-axis strategy.
Term exclusion rule, applied in a 20-result pretest

A term is rejected if more than 50% of the first 20 results are build/compilation errors or conceptual questions. Reporting the rejections is part of the replicability protocol. The five on record:

Rejected termMeasured reason
crash17/20 were build failures or segfaults with no resource metric at all
performance14/20 were feature requests ("performance roadmap"), not measured-cost reports
CUDAanchors the result in datacenter/desktop dGPU, the cohort the RQ excludes
bugorthogonal to the cost axis; does not discriminate
temperaturecollides with the LLM sampling hyperparameter temperature; replaced with thermal + throttl

The API constraint that determined the search design

Verified against the official REST documentation on 2026-09-29:

ConstraintValueDesign implication
Query length≤ 256 charsNot the bottleneck — ours run 71–90 characters
Boolean operators≤ 5The real bottleneck. Limits each query to ~6 terms
Results per query1,000Requires decomposition by repo: to avoid truncation
Authenticated rate limit30 req/minBackoff mandatory, 105 waits during actual collection

Recorded methodological consequence: the 26 keywords do not fit into 3 queries under the 5-operator cap.

The solution has two layers, both executed and deduplicated by (repo, issue_number):

  • Three primary queries, high-precision and reportable in the paper, each crossing a resource axis with a device cohort: memory × mobile; throughput/latency × Apple and GPU-equipped edge; thermal/energy × NPU, mobile, and embedded.
  • One KEYWORD-GRID: Cartesian product of 20 resource terms × 15 device terms, one atomic query per pair, 0 to 2 operators each. This is what gives full matrix coverage, and it is what explains the 3,600 queries executed (300 per repository × 12).

3.3 Mining: full provenance and two handled anomalies

Window2h442026-09-30, 02:13–04:57 UTC
Queries3,6003,743 HTTP requests
Rate-limit waits105automatic backoff
API version2022-11-28REST backend /search/issues

Per-repository provenance, with new and revisited issues per query, in data/msr/mining_provenance.json.

Anomaly 1, ROCm/ROCm returned nothing

The repository's 300 queries all failed with HTTP 422 ("the resources do not exist or you do not have permission"). The study therefore has 11 repositories, not 12. AMD coverage comes indirectly from llama.cpp and ollama, and indeed ROCm/HIP appears in 96 of the retained issues. Cause identified later (§3.1): the repository was renamed to ROCm/legacy-rocm-build, and under that name the pilot collection of the 86 obtained 304 issues. TARGET_REPOS still needs to be updated to the resolved name.

Anomaly 2, 5 queries truncated at the 1,000 cap, recovered by bisection

All five were ggml-org/llama.cpp combined with GGUF. Since the ordering is created desc, truncation always cut off the old tail. They were redone with recursive date-range bisection (mine_issues.py --requery-truncated, 98 requests, 6 minutes): +278 issues, 89% of them from 2023–2024, exactly the distribution the hypothesis predicts, which validates the fix.

Corpus: 7,611 → 7,889. This is the number used throughout the report. Where 7,611 appears in old annotations, it is the pre-bisection count.

3.4 Quality filter: the v1 criterion was replaced, and the measurement of why

The two criteria run over the same raw collection; only the filter changed. v1 is frozen in data/msr/baseline_filter_v1/ and remains reproducible with filter_issues.py --criterion v1.

v1 required model AND hardware AND numeric metric, searched for anywhere in the text. Measuring against the real corpus revealed the defect: llama.cpp's Eval bug template has the reporter paste the entire startup output, and 38% of that repository's raw issues carry this signature. The pasted log, on its own, satisfies all three gates:

v1 gateWhat the startup log provides for free, without the issue being about cost
Numeric metric0.15 MiB, 1941.02 MiB, 1187.01 ms from the load table
Modelthe model name appeared in 88% of retained issues
Hardwarebuild flags (NEON, aarch64, Metal), 57.6% of retained issues had only generic hardware

Aggravating factor: the pattern \bv?ram\b matched the VRAM that the runtime prints in every load output, dumping template, tokenizer, and kernel issues into the Memory category.

v2's conceptual shift, in one sentence

v2 does not look for "the issue mentions cost". It looks for "the issue records a cost expectation that was violated". The difference is operational, not rhetorical: an issue that passes this criterion carries both the expected and the observed value — in other words, it is already a test case for the predictor.

The three concrete changes

  1. Separate prose from log (extract_prose). Every regex now runs only over what the reporter wrote: fenced code blocks, <details>, HTML comments, runtime log lines, and key = value dumps are stripped out. This is the highest-impact fix.
  2. Change what is searched for. The expectation may be in the template's "What did you expect to happen?" section, or in markers such as theoretical … observed, 2x slower than, since build bNNNN, NPU slower than CPU.
  3. The scope gate became a penalty, not an exclusion. Measured: of v1's 1,002 cloud-cohort exclusions, 779 were merely consumer GPUs (desktop RTX), not datacenter. A personal desktop is a legitimate cohort, and the content of those issues (KV cache, quantization, scaling with context) answers RQ3 directly. In v2, only unambiguous datacenter is a hard exclusion; consumer GPU, build error, and feature request become score penalties (−2, −5, −3).
DimensionCriterion v1Criterion v2
Criterionmodel AND hardware AND metric, in the whole textviolated cost expectation, in the prose
Retained issues1,642 (21.6%)620 (7.9%)
Resource symptom in the title16.7%49.1%
Estimated precision (sample of 40, judged by hand)~17%~60%
Precision measured by labellingn/a45%
Hard exclusions3 (build, question, cloud)1 (datacenter cohort)

The two versions are not nested: v2 keeps 332 of v1's retained issues, discards 1,310, and recovers 277 that v1 had rejected. Source: data/msr/filter_v1_v2_comparison.md.

v2's three filters, in the order they are applied

Filter 1, measurability (hard condition). Requires at least one number with a unit (MB, GB, tok/s, ms, °C, mAh, W, %) in the prose. Without a number measured by the reporter, the issue cannot serve as an evaluation instance for a cost model. Discards 4,336 issues as the primary reason (4,412 in total lack a metric in the prose).

Filter 2, violated-expectation score. Sum of weighted signals; retains from score ≥ 10 up. The weights are all declared in VIOLATION_SIGNALS:

SignalWeightWhat it matches
teoria_vs_observado+3theoretical, computed, derived from, multiplier, observed … vs/but/however
expectativa_explicita+2expected, supposed to, should be/take/use/need/fit
regressao_versao+2since commit/version/bNNNN, worked fine in/before, regress*, bisect*
razao_inesperada+2N× slower/faster/more, twice as, half the
backend_pior_que_baseline+2npu|gpu|metal|vulkan|qnn|… slower than … cpu, falls back to cpu
escala_com_contexto+2kv cache, n_ctx, context length/size/window
comparacao_entre_configs+1more/less/slower than, vs, compared to, despite, identical

Cutoff sensitivity

CutoffIssues with score ≥ cutoff
≥ 62,820
≥ 81,584
≥ 10 (adopted)758
≥ 12298
≥ 14119
≥ 1638

Counts before scope exclusions.

Filter 3: scope (the only hard exclusion)

Unambiguous datacenter cohort, A100, DGX, EC2, Kubernetes, tensor parallel: 224 issues excluded. This is a scope boundary (the study is about on-device execution), not a quality signal.

Distribution: llama.cpp 133 · ollama 81 · onnxruntime 7 · others 3.

Discard reasons, in total

ReasonIssues% of discards
SEM_MENSURABILIDADE4,33659.7%
SCORE_BAIXO2,70937.3%
EXCLUSAO2243.1%
Declared limit of the score

The score is triage, not truth. It orders the corpus for manual labelling, which remains the study's actual measure. It also discards legitimate qualitative reports: llama.cpp#3422 ("AMD GPU slower than CPU") scores 17 and falls out for lacking a number outside the log. This is a conscious loss — without a number, the issue cannot serve as an evaluation instance for a cost model.

3.5 Sampling: stratified, proportional, with a fixed seed

Of the 620 filtered issues, 60 were drawn by stratified proportional sampling by repository, with a per-stratum floor, replicating the framework-stratification procedure of Islam et al. (2019). The seed is fixed (--seed 2028), which makes the sample exactly reproducible.

The row order is shuffled with the same seed, and this serves a control function: the Kappa milestones at 5%, 10%, 20%, 50%, and 100% are prefixes of the spreadsheet. If the 10% milestone's Kappa is already low, the protocol alignment meeting happens before spending the entire labelling effort. The protocol explicitly instructs: "stop at row 20 and run Kappa" — 20 rows lost instead of 60.

Acceptance criteria declared before labelling
Minimum Kappa
≥ 0.61, the Substantial band of Landis & Koch (1977)
Minimum n
20 for a milestone to be considered reliable — below that, a single disagreement shifts the Kappa by more than 0.2
If it fails
mandatory alignment meeting before continuing labelling

3.6 Labelling: the operational definition and the two annotators

The definition of RELACIONADO is the most important piece of the study, because it is what converts a text corpus into evidence. It requires all four conditions simultaneously:

Operational definition of RELACIONADO
  1. There is a cost expectation that was violated. Explicit ("expected ~30 tok/s"), derived ("the model is smaller, it should use less RAM"), or comparative ("2× slower since build bNNNN").
  2. The deviation is quantified. At least one number with a unit, written by the reporter about their own run. A number copied from a third-party benchmark does not count.
  3. The run is on-device. Mobile, embedded, laptop, or consumer desktop. Datacenter does not count.
  4. The deviation is attributable to a model, a configuration (quantization, context, backend), or an identifiable platform.

Missing any one → 0. This includes issues that are about cost but without a violated expectation (an optimization request), or functional bugs that merely mention numbers in a pasted log.

Edge cases decided before the round

SituationDecisionReason
Performance regression between versions, with a number1the expectation is the previous version
Accelerator (NPU/GPU) slower than the CPU, with a number1the expectation is that the accelerator is faster
Feature request that exists because cost is unpredictable1direct evidence of the problem
"It's slow" with no number0cannot serve as an evaluation instance
Crash with a log that contains MiB0incidental number, not a measurement
OOM on an A100 in a cluster0outside on-device scope

The two annotators have deliberately different decision rules. This is not an oversight: it is the design. If both applied the same criterion, the Kappa would only measure reading noise. Applying distinct criteria, it measures whether the definition is robust to two defensible readings of what counts as evidence.

Annotator 1, fidelity to the protocol

Wrote the protocol. Responsibility: fidelity to the written definition, not instinct about what "seems" relevant. Question: is there a cost expectation, stated or derivable, and a quantified deviation from it?

Labelled 27 as 1, 33 as 0.

Annotator 2, usefulness of the evidence

Did not write the protocol. Assesses whether the dataset supports evaluating the predictive model. Question: can a triple be extracted (model, hardware/platform, configuration) and an observed cost that the predictor would have to estimate without running?

Labelled 23 as 1, 37 as 0, systematically stricter (see §6.4).

Tiebreak procedure
  1. Every disagreement goes into disagreements.csv.
  2. The supervisor decides without seeing who labelled what.
  3. The decision goes into final_decision; discrepancy_resolved becomes TRUE.
  4. If the same type of disagreement appears 3 times or more, the operational definition is amended, and the amendment is recorded with its date. triggered, see §6.4
  5. The Kappa reported in the paper is the one at the 100% milestone before the tiebreak. After the tiebreak it is 1.0 by construction and measures nothing.

3.7 Discard audit: the half of the problem the funnel doesn't measure

The pipeline measures precision: of the retained issues, how many are genuine. On its own, it does not answer the complementary question, of the genuine issues that exist in the corpus, how many did the filter lose? Without that there is no answer to "what did you throw away?".

inverse_filter.py scores each discard by false-negative suspicion signals, with declared weights: sintoma_no_titulo +3, magnitude_explicita +3, eixo_ausente_no_retido +2, score_marginal (8–9) +2, hardware_especifico +1, engajamento_alto +1, metrica_apenas_no_log +1, against bug_correcao_no_titulo −3, build_no_titulo −3, cohort_datacenter −4.

A deliberate overweight, declared as such

eixo_ausente_no_retido is overweighted on purpose. The retained set has no Energy issues at all and only 6 Temperature issues; if the filter is blind to that axis, the discard pile is the only place it would show up. The overweight is a declared decision, not a hidden bias.

Suspicion stratumRangeIssuesIn the audit sample
high≥ 626422
medium3–51,01915
low≤ 25,9868
totaln/a7,26945

The allocation is not proportional: half the sample comes from the high-suspicion stratum, because proportional sampling would put almost everything in the low stratum, where the false-negative rate is near zero. The decisao column of the 45 rows is empty — the audit is a built instrument that has not yet been run.

The post-stratification recall estimation formula is already declared, so the result is not chosen after seeing the data:

FN = Σstratum ( hits / sampled × stratum_size )
TP = 620 retained × 45% precision ≈ 279
recall = TP / (TP + FN)

Example reading: if the audit finds false negatives in 20% of the high stratum, 5% of the medium, and 0% of the low, then FN ≈ 104 and recall comes out around 73%.

§4The funnel, end to end

Four stages, from 7,889 to 27. The bars show retention relative to the previous stage, not the absolute proportion, which would make the last stages disappear.

Raw issues7,889 GitHub Search API v2022-11-28 · 3 primary queries + KEYWORD-GRID · 3,600 queries over 11 repositories · issues created between 2017-12-03 and 2026-09-30
After automatic filter v2620 Retention of 7.9%. Discards: 4,336 with no numeric metric in the prose · 2,709 with a score below 10 · 224 by datacenter cohort
Sample for labelling60 Retention of 9.7%. Stratified proportional sampling by repository, seed 2028; the remaining 560 stay in reserve
Confirmed RELACIONADO27 Retention of 45.0%, this is the filter's measured precision. 33 rejected by consensus, 6 disagreements resolved by tiebreak

Extrapolating the 45% precision to the 620 filtered issues: about 279 genuine issues in the retained set.

Funnel by repository

Format adapted from Table 1 of Islam et al. (2019). The retention column reveals a difference in reporting culture between communities, not in software quality.

RepositoryRawFilterRetentionSampleConfirmed% Related
ggml-org/llama.cpp3,8633308.5%231043%
ollama/ollama1,7471247.1%10550%
mlc-ai/mlc-llm4344410.1%5120%
pytorch/executorch433184.2%3133%
microsoft/onnxruntime376287.4%4250%
google-ai-edge/mediapipe32251.6%2150%
lmstudio-ai/lmstudio-bug-tracker2973511.8%4250%
ggml-org/whisper.cpp13453.7%2150%
ml-explore/mlx1082018.5%33100%
google-ai-edge/LiteRT10298.8%2150%
apple/coremltools7322.7%200%
TOTAL7,8896207.9%602745%

mlx has the highest density of cost reports (18.5%) and mediapipe the lowest (1.6%). The reading is about reporting culture: mlx is used by people who measure; mediapipe gets a lot of integration issues.

Characterization of the retained corpus

Closed45573% of the 620
With linked fix38863%, the project acknowledged the problem
Comments4median · maximum 133
Time to close20 dmedian · p75 = 64 days
Open > 180 days32unresolved problems

§5Results and conclusions

5.1 Labelling reliability

Cohen's Kappa at the 100% milestone came out at 0.795, the Substantial band of Landis & Koch, above the 0.61 acceptance criterion declared before the round. The earlier milestones were all 1.000, which indicates the disagreement is concentrated in the second half of the spreadsheet (which, being shuffled, has no thematic ordering — so this is judgment disagreement, not warm-up noise).

Final milestone diagnostics

MetricValueReading
Cohen's Kappa0.795Substantial
95% CI[0.64; 0.95]lower bound above the criterion
Observed agreement (p₀)90.0%raw agreement rate
Expected agreement (pₑ)51.2%agreement attributable to chance
Prevalence index0.167< 0.6 → no deflation from a rare class
Bias index0.067< 0.2 → no severe systematic bias
PABAK0.800Kappa adjusted for prevalence and bias
Standard error0.079asymptotic

Prevalence and bias are reported because the Kappa paradox (high agreement with low Kappa) is exactly the risk posed by unbalanced samples. Here both indices fall in the safe range, which authorizes reading 0.795 as real agreement.

Confusion matrix

Ann. 2 = NOAnn. 2 = YES
Ann. 1 = NO321
Ann. 1 = YES522

The asymmetry is informative: 5 of the 6 disagreements are Annotator 1 accepting and Annotator 2 rejecting. This is not noise, it is a systematic difference in criteria, analyzed in §6.4.

Precision by score range

RangeConfirmed / sampledPrecision
10–1113 / 3339%
12–137 / 1937%
≥ 147 / 888%
Practical consequence

The score discriminates, but almost all of its power is at the top — between 10 and 13 the precision is indistinguishable from constant. So: to assemble the set of evaluation instances, use score ≥ 14 (119 issues, ~88% precision); to estimate population frequencies, use the cutoff of 10 with the 45% correction.

5.2 The serious correction: automatic entry-point classification is invalid

This result alone justifies the existence of manual labelling, and it is the kind of finding that needs to appear in the report even (especially) when it contradicts a claim we made earlier.

Entry pointHeuristic (620)Labelled (27)Reading
Artifact, the cost comes from a model property69.2%25.9% (n=7)overestimated by a factor of ~2.7
Toolchain, comes from the runtime, compiler, or backend23.7%74.1% (n=20)underestimated; it is the dominant slice
Platform, comes from the device's physical envelope7.1%0.0% (n=0)does not appear in the confirmed set
The relationship inverts, and why

The heuristic classified any issue mentioning quantization, GGUF, or KV cache as Artifact. But 66% of retained issues mention quantization, almost always as context for the report, not as the cause of the cost. It is the same disease as the v1 filter: matching on an incidental mention rather than on the issue's actual claim.

Concrete example: llama.cpp#29063 ("VRAM usage increased from b10680, SYCL backend") is a regression between builds, Toolchain. The heuristic marked it Artifact because the body cites Q4_K_M.

What this changes in the paper

The claim "69% of the corpus is, in principle, a function of artifact properties", which was in the earlier version of the analysis and in the slides, is wrong. The measured value is 26%, and the dominant slice is Toolchain: regressions between versions, backend choice, scheduler decisions. None of that is predictable from the weights file.

This narrows Stargazer v2's declarable reach and needs to be stated that way. With n = 27, the 95% CI for the 26% is wide (≈ 11%–46%), but the inversion relative to 69% falls well outside it: the qualitative conclusion is solid; the point estimate is not.

In the opposite direction, the resource category classification holds up reasonably well, which bounds the defect: the problem is in the origin taxonomy, not the symptom one.

CategoryHeuristic (620)Labelled (27)Reading
Memory63.9%55.6%dominant in both; moderate overestimation
Latency12.3%22.2%was underestimated
Throughput10.8%22.2%was underestimated
Temperature1.0%0.0%n/a
Energy0.0%0.0%the finding survives labelling
Other12.1%0.0%all rejected, independent validation

Outro (Other) disappearing entirely from the confirmed set is a useful cross-validation: the heuristic was already signaling that it did not know how to classify those issues, and labelling confirmed they were not evidence.

5.3 RQ1: memory is the cause, speed is the symptom

CategoryAs primary%As secondary
Memory39663.9%n/a
Latency7612.3%205
Other7512.1%n/a
Throughput6710.8%111
Temperature61.0%9
Energy00.0%6
Finding 1, the mechanism, not just the frequency

Memory dominates as the primary category (64%), and latency/throughput appear 205 and 111 times as the secondary category of those same issues. The recurring pattern is causal, not coincidental: a memory-estimation error pushes part of the model onto the CPU or triggers reallocation, and the user perceives this as slowness.

Design consequence: a predictor that gets memory right solves most of the problem, because observed latency is frequently a function derived from where the model ended up fitting.

5.4 The magnitude of the cost surprise

81 issues (13% of retained issues) report an explicit magnitude of degradation. This is the corpus's strongest descriptive statistic, because it depends on no classification at all — it is the reporter saying "N× slower" or "N% worse".

Median4.0×
p759.0×
p9050×
Maximum400×
Ratio rangeMentions
1.1–2×10
2–3×25
3–5×27
5–10×23
10–100×22
>100×5

Percentage degradation, when reported in % rather than as a ratio: median of 33%.

Interpretation, and the most direct argument for the paper

When a practitioner is surprised by cost, the median surprise is a factor of 4. This is not a calibration error, it is a qualitative prediction failure. A cost model that was off by 20% would be irrelevant next to this; what is at stake is the difference between "fits" and "doesn't fit", between "usable" and "unusable".

Corollary for evaluating Stargazer v2: the accuracy bar is generous. The target is not fine numeric precision, it is getting which side of the boundary the configuration falls on. And this number comes from the data, not from assumption.

5.5 RQ2: negative result, and where the variance actually is

RQ2 asks which model × hardware combinations generate the most problems. The test is a lift test: the observed frequency of the pair divided by the expected frequency if model and platform were independent. Lift ≈ 1.0 means the pair is simply the product of the marginal frequencies — that is, there is no real concentration.

QNN/Hexagon × hexagon-npu31.0
OpenCL × hexagon-npu24.8
WebGPU/wasm × iphone13.9
WebGPU/wasm × ios11.2
WebGPU/wasm × android7.5
ROCm/HIP × hexagon-npu4.2
Vulkan × iphone3.8
glm × apple-silicon1.54
mistral × apple-silicon1.23
gemma × apple-silicon1.13
qwen × apple-silicon (n=90)1.06
llama × apple-silicon (n=111)0.81
llama × ios0.54

Common linear scale, maximum 31.0. The red dashed line marks lift = 1.0 (independence). Blue bars: the backend × platform axis. Gray bars (red label): the model × hardware axis, all hugging the independence line.

RQ2, as written, has a negative answer

All model × hardware lifts fall between 0.54 and 1.54, indistinguishable from independence. The apparently "hot" pairs are an artifact of the marginals: llama appears in 421 of the 620 issues and apple-silicon in 201, so the llama × Apple Silicon pair with n=111 is exactly what would be expected by chance.

Reporting this is worth more than forcing a ranking of pairs the test does not support.

Recommendation: reformulate RQ2 as backend × platform

Lifts of 31.0 and 24.8 against ~1.0. The concentration of problems is backend-specific, not model-specific. The reformulated version, "which backend × platform combinations concentrate cost problems?", has an answer, is statistically supported, and is more actionable: the developer chooses the backend, not the SoC.

Distribution by backend (74% of issues name at least one)

Backendn%Dominant category within the backend
CUDA20032.3%Memory (67%)
Vulkan13421.6%Memory (70%)
Metal11618.7%Memory (57%)
ROCm/HIP9615.5%Memory (79%)
MLX6710.8%Memory (49%)
WebGPU/wasm355.6%Memory (51%)
SYCL/oneAPI233.7%Memory (87%)
QNN/Hexagon203.2%Memory (50%)
XNNPACK152.4%Latency (47%)

Memory dominates within every backend (49–87%), independent confirmation of Finding 1. XNNPACK is the only exception, and it is precisely the mobile-CPU backend, where there is no cross-device memory transfer to get wrong. The exception reinforces the mechanism rather than weakening it.

5.6 RQ3: the problem isn't quantizing the model, it's quantizing the cache

Signaln% of retained
Mention a quantization scheme40966%
Mention KV cache / context24940%
Of those mentioning KV cache, are Memory22490%

Most-cited schemes: q8_0 (127), q4_k_m (122), f16 (81), q4_0 (64), bf16 (39), fp16 (36).

Counter-intuitive finding

q8_0 leads, and appears more often as a KV cache type than a weights type. The highest-magnitude issues involving quantization are not about quantizing the model, they are about quantizing the cache. See llama.cpp#27109 (prefill drops 20×), #27761 (pp512 drops 68%), and #10552 (−16% with a draft model) in §6.1.

Empirical justification for a predictor feature

90% of issues mentioning KV cache are memory issues. It is the component that grows linearly with context and that no weights-file-based estimate captures. This is the measured justification for including n_ctx as a mandatory input feature.

Important correction on the energy axis, the claim changed

The retained set has zero Energy issues and 6 Temperature issues. The initial reading was "the energy axis is not reported." The discard audit showed this reading is wrong: 77 discarded issues mention battery, energy, power, temperature, or throttling — 48 via SCORE_BAIXO, 27 via SEM_MENSURABILIDADE, 2 via exclusion.

The two claims have opposite implications: "not reported" → RQ1 needs to narrow or change source. "Reported, but without a number" → the measurability criterion is what is blind to this axis, and the fix belongs in the filter, not the source. The clearest case is llama.cpp#8760 ("quants IQ1xx/IQ2xx/IQ3xx are overheating, CPU 90C"): it has a measured temperature in the title and falls out for lacking a metric in the prose.

§6The issues found, examples, with the reasoning behind each decision

This section exists so the criterion can be audited concretely, not only in the abstract. Each record carries the issue's claim, what the reporter measured, and why the issue was accepted or rejected. All identifiers are direct links.

6.1 The strongest evaluation instances

These are the issues that, on their own, support the paper's argument. The criterion that sets them apart is not severity, it is having both sides of the deviation measured by the reporter, which makes them directly usable as a test case for the predictor.

pytorch/executorch#22016confirmedscore 20
MLX iOS: whisper-small bf16 uses ~6.7× its file size in RSS and is jetsam-killed, while every sibling stays under 2×
What the reporter did: exported six Whisper variants to MLX and measured RSS on a freshly launched process for each, with a stable baseline of 554–556 MB. Result: tiny/bf16 uses 1.66× the file size; small/bf16 uses 6.7× and is killed by jetsam at 3.80 GB on an iPhone 16.
Why it matters: it is the direct, measured refutation of the heuristic "memory ≈ weights file size." And it is a controlled refutation, same family, same runtime, same harness, same device, varying only size and precision. Methodologically it is almost a factorial experiment that Stargazer v2 would have to reproduce.
MemoryPlatformiPhone 16 · MLX · bf16
ollama/ollama#17099confirmedFigure 1 candidate
0.31.2 regression: memory estimate inflated ~1.2 GiB → no longer fits in VRAM → 7× slower generation (33.8 → 4.7 tok/s)
What the reporter did: Ollama already has a memory estimator. Between 0.31.1 and 0.31.2 it started overestimating by 1.2 GiB (18.8 → 20.0 GiB for the same model and num_ctx), the model no longer fit in 24 GB of VRAM, the scheduler offloaded 10% to the CPU, and generation dropped from 33.8 to 4.7 tok/s.
Why it matters: there is no need to argue the problem exists — the ecosystem already tried to solve it, and there is a quantified record of the failure, with the estimation error and the cost consequence measured on both sides. It is the paper's natural Figure 1.
MemoryToolchainregression between versions
qwen2.5vl:7b uses significantly more RAM than qwen3-vl:8b despite smaller architecture and identical quantization
What the reporter did: derived the theoretical KV cache from the architecture's properties (28 layers, 4 KV heads, head dim 128 → ~0.44 GB @ 8k, ~0.88 GB @ 16k), measured the real one (an increase of ~2 GB when doubling the context), and concluded a 4–5× multiplier over theory, raising three hypotheses (KV in fp32, duplication, extra allocation).
Why it matters: it is exactly the computation Stargazer v2 automates, and it fails in the hands of someone who knows how to do it. If the analytical derivation from the architecture were only slightly off, the product would be unnecessary.
MemoryArtifacttheoretical vs. observed
llama-tts: qwen3-tts default context (32768) allocates 3.5 GB of KV cache, 4096 would suffice
What the reporter did: calculated the real need from the codec rate (12.5 tokens per second of audio): ~2,100 cells for 100 s of audio, ~900 for the default n_predict. The 32,768 default allocates 3,584 MiB, bringing the total to ~7.1 GB.
Why it matters: the cost here comes neither from the model nor the hardware, it comes from a configuration default. This is the Artifact category in its pure state, and is trivially predictable if the predictor knows n_ctx.
MemoryArtifactKV cache
[Bug] Speculative decoding results in huge memory usage
"I expect it to use a lot less memory since the models are just 7B and 13B"
What the reporter measured: a KV cache of 50,669 MB against 9,462 MB of parameters, on a Jetson Orin. A KV/weights ratio of 5.4:1.
Why it matters: any estimator starting from weights size is off by more than 500% in this case. And the cohort is real edge hardware (Jetson Orin), not desktop — the closest to Stargazer v1's hardware.
MemoryArtifactexplicit expectation
ggml-org/llama.cpp#27109 · #27761confirmedcentral evidence for RQ3
Quantizing the KV cache is not a monotonic memory ↔ quality trade-off
#27109: switching the K cache from q8_0 to q4_1 drops prefill from 991–1,276 t/s to 34 t/s (~20×) on an RTX 3090, with generation unchanged.
#27761: on ROCm, any KV cache type outside q8_0/q8_0 and q4_0/q4_0 fragments the graph from 2 to 34 splits, pushes ~550–580 MiB to the host, and drops pp512 by 68%. The same build on Vulkan does not have the problem.
Why they matter: they disprove the intuition that quantizing the KV cache is a predictable trade-off. The cost depends on the backend, and the effect is non-linear. This is direct evidence for RQ3 and, at the same time, for reformulating RQ2.
ThroughputArtifactbackend-dependent
[Vulkan] LLM decode ~12% slower than XNNPACK on Adreno
What the reporter did: Qwen3 4-bit on a Galaxy S26 Ultra (Adreno 840), medians with a cold device and interleaved runs: Vulkan decode 98.0 against XNNPACK 109.0 tok/s, but Vulkan prefill is ~2× faster. It further quantifies that the q4gsw GEMV is ~74% of GPU time at ~44.5 GB/s with the GPU 100% busy.
Why it matters: it is the mobile cohort with a serious measurement methodology, and shows that the accelerator choice flips sign depending on the phase (prefill vs. decode). A cost predictor that returns a single number per backend is wrong by construction.
ThroughputToolchainGalaxy S26 Ultra · Adreno 840
ollama/ollama#12353recovered by v2
Feature Request: Auto-size num_ctx to a user VRAM budget (and recalc on model switch)
"Right now, users must guess a safe num_ctx. If it's too high, VRAM overflows and Ollama may slow down or fall back to CPU, with no clear feedback."
Why it matters: it is not a report of pain, it is Stargazer v2's specification written by a user, including the requirement to recalculate on model switch and to respect the GGUF limit.
Methodological value: the v1 filter discarded this issue as a "feature request." It was precisely cases like this that turned the scope gate into a penalty in v2, and it is the example that justifies the criterion change with a concrete, high-value recovered case.
explicit ecosystem request

6.2 The issues that bound the predictor's scope

These three are equally important, and for a different reason: they show what Stargazer v2 cannot predict. The paper is stronger for stating them, because a reviewer who found them alone would conclude we had not looked.

ollama/ollama#16051declarable limit
MLX bf16 cold prefill is 60–400× slower than warm, even when peak memory fits in physical RAM
What the reporter did: on an M3 Ultra with 96 GB, the first prefill of an MLX bf16 model is 60–400× slower than subsequent ones. Ruled out the paging explanation using gemma4:26b-mlx-bf16, whose 47.13 GiB peak fits comfortably. Decode is unaffected.
Why it bounds the scope: the same (model, hardware, configuration) produces two costs separated by two orders of magnitude, depending only on warm-up state. No static predictor solves this. This is the issue to cite by name when the paper states the limit.
ggml-org/llama.cpp#21164cost is a function of topology
Vulkan regression with 3 GPUs vs 2 GPUs: Qwen3.5 PP drops from ~3500 tok/s to ~350 tok/s
What the reporter did: three Radeon AI PRO R9700 cards (96 GB total). The 122B model works with 2 GPUs and collapses with 3, with a working baseline at commit 66d65ec.
Why it bounds the scope: the cost is a function of hardware topology, not of the model. No artifact feature predicts this.
Heavy throttling during token generation on Apple Silicon
What the reporter did: MacBook Pro M3 Max 128 GB, Qwen 72B Q4_0, high-performance mode on a 96 W supply. Measured 60–70 °C at peak and explicitly concluded the throttling is not thermal.
Usage warning: it is the corpus's only substantive issue on the thermal axis, and it rejects the thermal hypothesis. It does not support a claim about thermal throttling — it supports the claim that there is degradation under sustained load whose cause the reporter could not attribute. Citing it as evidence of a thermal problem would misread the data itself.

6.3 Rejected by consensus: the criterion seen from the negative side

A criterion is only auditable if the discards are also inspectable. All the issues below passed the automatic filter (score ≥ 10) and were rejected by both annotators. The reason column cites the protocol step that failed: Step 1 is "no violated cost expectation"; Step 2 is "no deviation quantified by the reporter".

IssueTitleRejection reason
llama.cpp#12390SYCL bug: DeepSeek-V2-Lite-Chat-Q4_K_M does not work as expectedStep 2, the only numbers are in the startup log; "does not work as expected" does not state a cost
llama.cpp#29082[Vulkan] GGML_ABORT cache_k_l0 in Vulkan buffer on SWA models, regression 2.40/2.41 vs 2.39Step 1, the expectation is not to abort: a functional regression, not a cost one
llama.cpp#1240QX_4 quantizationStep 1, a proposal for a new quantization scheme, not a violated expectation
llama.cpp#23335Eval bug: draft-mtp changes deterministic output on Qwen3.6 MTP modelStep 1, deterministic output divergence, not cost
onnxruntime#25472std::vector bounds assert on Pi Zero 2 W (arm64, ORT 1.22.0) when running BGE-micro-v2Step 2, the 512 MB is the device's spec, not a measurement of consumption
mlc-llm#2328[Bug] InternalError: Vulkan Error, code=-4: VK_ERROR_DEVICE_LOSTStep 2, the only number is 2.00GHz (clock), not a cost measurement
llama.cpp#19844Misc. bug: Llama-3.1-8B-Instruct crash in Vulkan Intel LNL iGPUStep 1, crash above 4K tokens; functional expectation, no quantified cost
llama.cpp#13865Eval bug: KV cache shifting does not work for Qwen2.5VLStep 1, an expectation of correctness, not of cost

The dominant pattern across the 33 rejections is a single one: a functional bug mentioning incidental numbers in a pasted log. This is exactly the false positive the v2 filter was designed to reduce, and it did reduce it from ~83% (v1) to ~55%, but did not eliminate it.

6.4 The six disagreements: and what they revealed about the definition

Six of the 60 issues (10%) received different labels. All went to tiebreak and are resolved. But the relevant finding is not the number: it is that five of the six share the same cause.

IssueAnn. 1Ann. 2Annotator 2's reason for rejectingTiebreak
llama.cpp#93210"4 cores, amd, linux does not identify a reproducible platform"1
llama.cpp#68110same reason, platform not identified1
llama.cpp#1055210"no GPU or platform identified, scenario not reproducible"1
mlx#362510"no inference model identified, just an operation"1
mlx#393210"compilation primitive, no inference model"1
llama.cpp#2138501(reverse direction) Ann. 2 accepted: "complete triple with measured tok/s"0
Rule 4 of the tiebreak procedure was triggered

The protocol says: "if the same type of disagreement appears 3 times or more, the operational definition of RELACIONADO is amended". Here the same type appeared 5 times: Annotator 2 requires the triple (model, platform, configuration) to be reproducible; Annotator 1 only requires the deviation to be attributable.

These are two defensible readings of condition 4 of the definition, and the current text does not decide between them. The tiebreak resolved case by case in the direction of attributability ("a vague platform does not void attributability"), but this needs to become a written amendment, dated, before the definitive human round, or the two human annotators will reproduce the same disagreement and the Kappa will measure disagreement over the definition, not over judgment.

This is the most important item to ratify with the advisor, and it is the main value delivered by the pilot round: it found the ambiguity at a cost of zero human hours.

6.5 Suspected false negatives: what the filter likely lost

Outputs from the discard audit, ordered by suspicion score. The decision column is empty: these are candidates, not confirmed false negatives. But reading the titles already indicates the filter errs systematically, not randomly — the pattern is an issue with a clear comparison in the title and a number only inside the log.

Susp.IssueTitleDiscard reason
10ollama#17362Gemma4 12b MLX generates significantly slower than Gemma4 26b MLXSEM_MENSURABILIDADE
9onnxruntime#32218CoreML EP: ~10× inference slowdown on iOS in 1.29 vs 1.28 (ConvNeXt)SEM_MENSURABILIDADE
9llama.cpp#14201LLAMA-SERVER is 40% slower than LLAMA-CLI when using identical parametersSCORE_BAIXO: 9
9llama.cpp#8760quants IQ1xx, IQ2xx, IQ3xx are overheating (CPU 90C), Ryzen 9 7950x3dSEM_MENSURABILIDADE, thermal axis
8llama.cpp#27191Adreno/Turnip: GPU clock throttling between submissions hurts tg128SCORE_BAIXO: 8, thermal axis
8mediapipe#6193MediaPipeTasksVision Memory Leak after 10 minutesSEM_MENSURABILIDADE
8onnxruntime#27513Severe CPU Performance Regression on Intel vs Snapdragon/ARMSEM_MENSURABILIDADE
7llama.cpp#3422[User] AMD GPU slower than CPUSEM_MENSURABILIDADE, score 17, no number in the prose
7llama.cpp#5965Using OpenCL on Adreno & Mali GPUs is slower than CPUSEM_MENSURABILIDADE
7onnxruntime#10208gpu is 4 times slower than cpu on jetson xavierSEM_MENSURABILIDADE

Source: data/msr/discard_audit.md, sections 4 and 5. Note that llama.cpp#3422 has a score of 17, well above the cutoff, and is discarded by the hard measurability condition. This is the conscious loss declared in §3.4.

6.6 The 27 confirmed issues, in full

Complete list of the confirmed set, for direct inspection. Those marked with D came from the tiebreak. The category and entry-point columns are Annotator 1's, and they are what produce the corrected distribution in §5.2 (7 Artifact · 20 Toolchain · 0 Platform).

27
IssueTitleCategoryEntry point
ggml-org/llama.cpp#29063Eval bug: VRAM usage increased from b10680 (SYCL backend)MemoryToolchain
google-ai-edge/mediapipe#6270`RuntimeError: memory access out of bounds` loading gemma-4-E2B-it-web.task on Chrome 146 / macOS / Apple M4MemoryToolchain
lmstudio-ai/lmstudio-bug-tracker#2250MLX models ignore every user-configured context length, "context auto-fit" always overrides it to the RAM-fitted maximumMemoryToolchain
ollama/ollama#12342Bug: inconsistent to use VRAM and GTT of iGPU of AMD Ryzen AI ProcessorMemoryToolchain
microsoft/onnxruntime#20709[Mobile] Subgraphs duplicate initializers in RAM during executionMemoryToolchain
ml-explore/mlx#3658Allow force using fused kernel in scaled_dot_product_attentionMemoryToolchain
ollama/ollama#18074Granite 4.2 models (8B/3B) do not respect safe default context ( eg. 4096) base on available VRAM and cause OOM killsMemoryArtifact
ggml-org/llama.cpp#27937llama-tts: qwen3-tts default context (32768) allocates 3.5 GB of KV cache, 4096 would sufficeMemoryArtifact
ggml-org/llama.cpp#21164Vulkan regression with 3 GPUS vs 2 GPUS: Qwen3.5 PP drops from ~3500 tok/s to ~350 tok/s vs commit 66d65ec (35B unaffected)ThroughputToolchain
ollama/ollama#170990.31.2 regression: vision model (gemma4:31b) memory estimate inflated ~1.2 GiB → no longer fits in VRAM → 7x slower generation (33.8 → 4.7 tok/s)MemoryToolchain
ollama/ollama#1800OOM errors for large context models can be solved by reducing 'num_batch' down from the default of 512MemoryToolchain
ggml-org/llama.cpp#932 Dperf: Investigate performance discrepancy with llama-rs - 1.5x-2x slowerLatencyToolchain
google-ai-edge/LiteRT#7787Tensor SDK Beta, Dispatcher / runtime protocol mismatch makes AOT path unusable on Pixel 10 Pro XLLatencyToolchain
ggml-org/whisper.cpp#3088Memory Leak in whisper_full without Core ML (master branch) on macOS Apple Silicon?MemoryToolchain
ggml-org/llama.cpp#23181Misc. bug: cudaGraphInstantiate OOM during prompt-cache checkpoint creation under sustained unique-prompt load (Q4_K_M MoE + --n-cpu-moe; --cache-ram 0 does notMemoryToolchain
pytorch/executorch#22968[Vulkan] LLM decode ~12% slower than XNNPACK on AdrenoThroughputToolchain
ggml-org/llama.cpp#27761Misc. bug: ROCm FA: only q8_0/q8_0 and q4_0/q4_0 KV cache works, all other types cause 34 graph splits (pp512 drops ~68%)ThroughputArtifact
ggml-org/llama.cpp#26396SYCL: b10216 oneMKL FA path regresses 200K prompt prefill on Arc Pro B70 by ~35%ThroughputToolchain
ml-explore/mlx#3625 D[Performance] conv_general 5D (3D convolution) is 2-5x slower than equivalent per-frame 2D convLatencyToolchain
ggml-org/llama.cpp#27109CUDA: 4-bit KV cache (q4_1/q4_0) collapses prefill to ~34 t/s on qwen35 hybrid (RTX 3090, MMQ guard passes)ThroughputArtifact
microsoft/onnxruntime#29538[Performance] Large CPU memory regression starting in 1.24 (Java, macOS arm64) for fully-convolutional models with dynamic input shapesMemoryToolchain
ml-explore/mlx#3932 DMemory leak when compiled function contains multi-output opMemoryToolchain
ollama/ollama#17829MLX engine: no prompt/prefix caching between requests (full re-prefill every agent step)LatencyToolchain
ggml-org/llama.cpp#10552 DMisc. bug: [server] Using q8_0 for KV cache reduces performance when also using a draft modelThroughputArtifact
mlc-ai/mlc-llm#1827[Bug] Speculative decoding results in huge memory usageMemoryArtifact
ggml-org/llama.cpp#681 Dq4_1/f16 model is slowLatencyArtifact
lmstudio-ai/lmstudio-bug-tracker#2074Responses API `previous_response_id` chaining re-prefills an exponentially-growing context (10–30× the real conversation), multi-turn far slower than chat-compLatencyToolchain

27 of 60 sampled issues · filter's measured precision: 45% · generated from data/msr/issues_sample_eval.csv.

§7The literature: what was read and what each paper does for the research

The reading library has 11 papers in 4 groups, all with a versioned PDF in references/ and a README per group explaining each one's role in the text. The organization is not thematic for convenience: each group answers a different objection an ICSE reviewer will raise.

The thesis the reading needs to support

The inference cost of a model on a device (memory, latency, energy, thermal behavior) is only discovered after the model reaches the device, and no release process requires that cost to be estimated beforehand, for a heterogeneous fleet.

The Phase 0 gate found no paper that defines the problem in these terms, but found many that measure or predict inference cost. Hence the reading's three tasks: (a) show the phenomenon is real and quantified; (b) map the estimators closely enough that the gap argument survives a reviewer who knows them; (c) import framing, empirical method, and precedent from software engineering.

Group A: evidence that the cost is real and shows up late

The two measurement studies that demonstrate the phenomenon. They serve as motivation and as a controlled counterpart to the issue corpus: they measure in the lab what the issues report in the field.

Tummalapalli et al. (2026), LLM Inference at the Edge: Trade-offs Under Sustained LoadarXiv:2603.23640
Core idea: on-device LLM performance is bound by thermal management, not peak compute, and the binding constraint only shows up under sustained load.
Evidence: Qwen 2.5 1.5B at 4 bits across four platforms (Raspberry Pi 5 with a Hailo-10H NPU, Galaxy S24 Ultra, iPhone 16 Pro, RTX 4050 laptop), a fixed 258-token prompt, 20 iterations. The iPhone loses almost half its throughput within two iterations; the S24 Ultra hits an OS-imposed GPU frequency floor that ends the inference; the RTX 4050 sustains 131.7 tok/s at 34.1 W; the Hailo-10H holds 6.9 tok/s under 2 W with near-zero variance.
How it helps the research: it is the gate's motivation and requirement. It separates peak capacity from deliverable capacity, which is the distinction a release gate needs to encode — a gate that checked a single inference call would have approved the iPhone's configuration. And the authors' own disclaimer (platform characterization for a single model and prompt type) reinforces the gap: the best characterization available refuses to generalize to a fleet.
Limits: one model, one prompt type, four platforms. It is proof of existence of thermal collapse, not a distribution over devices.
Cai et al. (2026), Is Your NPU Ready for LLMs? (PowerBench)arXiv:2607.05475
Core idea: mobile LLM inefficiency comes mainly from the software layers above the hardware (operator strategies, thread configuration, sleep/wake coordination) and is invisible to device-level energy measurement.
Evidence: five frameworks across CPU, GPU, and NPU backends. Framework choice alone produces up to a 10× difference on the NPU. Prefill is compute-bound and favors the NPU; decode is memory-bound and favors the CPU. Scheduling inefficiencies waste up to 40% of energy, and an energy-oriented configuration cuts NPU consumption by up to 54.8%.
How it helps the research: two functions. (1) Kills the most obvious objection to the paper, "just publish the cost in the model card": the same weights on the same silicon cost an order of magnitude more energy depending on the runtime, so cost is not a property of the artifact. (2) Provides the proof-of-concept instrumentation: every gate needs ground truth to validate against, and device-level energy meters do not give that at backend granularity.
Limits: the 54.8% saving comes from expert tuning, not an automatic procedure, and nothing here predicts cost for a device that was not measured.
convergence with the corpus
Point of contact with the MSR: Cai et al.'s thesis (cost is a function of the software layer, not the artifact) is exactly what labelling independently measured in §5.2, 74% of confirmed issues are Toolchain, not Artifact. Two distinct methodologies converging on the same finding is a strong argument, and it is worth stating that way in the paper.

Group B: the state of the art in estimation (read adversarially)

These four are read with a fixed question: what exactly does this paper not claim, and can that be said in a sentence a reviewer would accept? CARB and Tu et al. are the two closest neighbors found in Phase 0, that is, the biggest risk to the originality argument.

Zhang et al. (2021), nn-MeterMobiSys 2021canonical reference
Core idea: latency should be predicted at the granularity of kernels, the fused operator groups the runtime actually schedules, rather than from model-level proxies like FLOPs.
Evidence: automatic detection of the backend's fusion rules, adaptive sampling, and evaluation on four edge platforms with 26,000 generated CNN models. Accuracy within 10% error reaches 99.0% on CPU and Adreno GPUs, against 22.1% for FLOPs-based prediction.
How it helps the research: the committee will assume it has been read, so not citing it is not an option. It sets the accuracy bar, and it is necessary to know that the bar was set on static-graph CNNs before promising the same for autoregressive inference. Its weakness is also instructive: every new device requires its own profiling campaign, which is part of why a gate for an entire fleet does not exist yet.
Limits: 2021, CNNs, latency only.
Tu et al. (2026), Transferable Latency Prediction for Fast LLM ScreeningarXiv:2607.21602closest neighbor
Core idea: on-device latency can be predicted from static model descriptors fused with dynamic hardware telemetry, and the predictor transfers to a new device with light calibration.
Evidence: a gated predictor that treats each request as a hardware+runtime+model+prompt configuration, separating prefill from decode and accounting for DVFS and thermal variation. On a Pixel 8 it reaches an R² of 0.960. Cross-calibration from Pixel 8 Pro → Pixel 8 moves the R² from a negative value (≈ −0.974) to 0.940.
How it helps, and where it is a threat: it is the work closest to our territory: it has the fleet, it has pre-deployment screening as a use case, and it handles thermal variation. The distinguishing sentence: Tu et al. offer a better predictor so that whoever has already decided to pick a model picks it well, but (a) they do not claim that shipping without this estimate is a process defect, and (b) they predict one dimension of cost.
Number to reuse: the R² drop from negative to 0.940 quantifies how badly a latency model travels between two phones in the same family. It is the most compact argument that fleet heterogeneity is a first-order problem.
Limits and a bibliographic caveat: only latency — memory, energy, and thermal state are inputs, not predicted outputs. Anomaly recorded in Phase 0: the arXiv identifier (2607) and the reported submission date (11/05/2026) do not match; confirm against the arXiv record and never derive the date from the identifier.
Nguyen and Pan (2026), CARBarXiv:2608.10506most dangerous neighbor
Core idea: energy, latency, and peak memory behave differently from one another, and characterizing how each responds to architecture and load enables a two-stage screening that discards most candidates before any of them run on the target.
Evidence: 13,419 CNN configurations measured on an RTX 5090 and an RTX 3080. Energy and latency diverge by up to 3× under high load. All three targets are predicted with R² ≈ 0.99. Memory predictions transfer between the two GPUs; energy and latency require per-platform models. The screen removes >90% of candidates in seconds.
Why Phase 0 called it the most dangerous: it predicts exactly the three costs that matter to us, before deployment, and uses the word screening. Reading it carefully is defensive work. It must be possible to say, with a page reference, that (a) the platform set is two desktop GPUs, so there is no device-diversity problem, and (b) it frames screening as an efficiency gain for design-space exploration, not as a step the release process is failing to take.
Finding to build on: transferability differs by metric. If memory transfers between platforms and energy/latency do not, then a fleet gate cannot treat cost as a single thing. This is an argument CARB hands us for free.
Limits: CNNs and not LLMs; two desktop GPUs and not devices; no fleet and no process argument.
Imai et al. (2024), Predicting LLM Inference Latency: A Roofline-Driven ML MethodML4Sys @ NeurIPS 2024cloud paper
Core idea: an analytical hardware model (roofline) gives a physically grounded estimate, and a regression model trained on historical runs corrects the residual the analytical model ignores. The hybrid beats each component alone.
Evidence: nine model-description features + three operational ones + the roofline estimate, evaluated on vLLM and Triton with four small open models on an A100. Against a regression-only baseline, R² improves 12% and MSE drops 80% on vLLM.
How it helps the research: it is cited for the method, not the results, and that needs to be said when citing it, because the target is cloud serving, outside our scope. The value: a fleet gate faces a data problem (profiling thousands of device configurations to train a purely empirical predictor is not feasible), and putting a physical model in front and learning only the residual is the standard answer. This is its compact example, and it is the method our bench experiments' Roofline validation already reproduces.
Their limitation with a direct analog in our case: they train on fixed generation lengths, while the real length is not known in advance. On-device, memory and energy depend on prompt and context, also unknown at release time, which pushes the gate to express cost as a distribution or worst case. This is the bridge to Singularity, in Group C.

Group C: framing and method transfer

The paper is a software-engineering paper, and the committee judges process arguments by software-engineering standards. Varghese provides the agenda framing; Singularity provides the worst-case method and the precedent that resource cost is a testable property before release.

Varghese et al. (2016), Challenges and Opportunities in Edge ComputingIEEE SmartCloud · position paper
How it helps the research: it is the citation that lets us say this is a recognized agenda, not an invented problem. The "opportunity for standards and benchmarks" it lists is the half the community fulfilled only halfway: we have plenty of benchmarks and still no admission criterion. It also lets us date the gap: the agenda is ten years old, the measurement instrumentation arrived, the release step did not.
Limits: 2016, written before on-device LLM inference existed. Cite for framing and vocabulary, never as evidence about LLMs.
Wei et al. (2018), Singularity: Pattern Fuzzing for Worst Case ComplexityESEC/FSE 2018
Core idea: instead of searching for a single slow input, search for an input pattern, a generator that produces an infinite family of growing inputs with the same structure, and use it to expose worst-case resource usage as a black-box property, before a user finds it.
Evidence: genetic programming over recurring computation graphs, scored by instruction count. Worst case found for 16 of 17 textbook algorithms, plus DARPA STAC applications and five previously unknown performance bugs in Guava, JGraphT, and Vavr.
How it helps the research, three transfers: (1) Precedent: the SE community already accepts that resource cost that only manifests under certain inputs is a defect class searchable before release. (2) Worst-case framing: a gate cannot be defined over average behavior, and our issues are mostly about long prompts, long context, and long sessions — a family of growing prompts is exactly a "pattern" in Singularity's sense. (3) Black box: on-device runtimes tend to be closed, so a technique that needs no code access is the realistic one.
Limit of the transfer: it addresses the algorithmic complexity of deterministic programs measured in instruction count, not energy or thermal behavior across a fleet. The honest transfer is of the question ("what is the worst case, and can it be found before shipping?"), not of the technique, because our cost depends on hardware state, not just input structure.

Group D: empirical method for the issue corpus

These three are not about inference cost. They are the software-engineering method behind our half of the paper: how a corpus of real faults is mined, organized, and defended. They are read against the protocol, not against the gap argument, and are the direct basis for everything in §3.

Humbatova et al. (2020), Taxonomy of Real Faults in Deep Learning SystemsICSE 2020
Evidence: 1,059 artifacts (477 Stack Overflow discussions, 271 GitHub issues and PRs, 311 commits) across TensorFlow, Keras, and PyTorch, plus structured interviews with 20 practitioners. Produces a taxonomy of 5 top categories with 92 leaf types from 375 instances; a validation survey with another 21 developers confirms that 13 of 15 categories had been experienced by at least half of respondents.
How it helps the research: it is the ICSE-stamped method template. Our corpus is the same type of object (real faults mined from repositories), and this is the accepted procedure for turning mined artifacts into a taxonomy and validating it with practitioners.
And it marks the gap precisely: the five categories cover correctness and training, with GPU usage as the only resource dimension. There is no category for inference cost appearing across a device fleet, which is exactly the family of faults our corpus is built around.
Thomas et al. (2025), muPRL: A Mutation Testing Pipeline for DRL based on Real FaultsICSE 2025
Evidence: mining 2,787 artifacts (≈3.6× the earlier corpus) produces a taxonomy of 48 RL fault types across 8 categories; 8 of 15 derived mutation operators are implemented and evaluated on CartPole, LunarLander, Parking, and Humanoid with DQN, PPO, SAC, and TQC. Mean killability ≈72%, and muPRL distinguishes strong from weak test generators far better than the baseline (sensitivity up to 1.0 against a maximum of ≈0.04).
How it helps the research: it closes, from the other side, the loop Singularity opens. Singularity argues resource cost under certain inputs is a searchable defect class; muPRL shows the same community routinely converting mined real faults into a concrete pre-release adequacy instrument. Together, they let us argue that a release gate for inference cost is not an exotic proposal, but the missing instance of an established pattern: catalog real faults → derive a check → run it before shipping. It shares authorship with the taxonomy, which evidences the lineage.
Limit of the transfer: the operators perturb policies, not resource envelopes. What transfers is the pattern, not the mutation machinery.
Codabux et al. (2025), Teaching Mining Software Repositoriesbook chapter · arXiv:2501.01903Phase 1 method
Core idea: an MSR study is a defined procedure, goals via Goal-Question-Metric, explicit inclusion and exclusion criteria, disciplined cleaning, compatible analysis, named threats to validity, and its credibility rests on following that procedure, not on dataset size.
How it helps the research: it is the standard this entire report is measured against, and the citation to defend every design choice. Every decision the protocol leaves open — repository selection, score cutoff, per-repository sampling quota, the "measured number" heuristic — is a construct- or external-validity question this chapter names. Citing it lets us present these choices as the deliberate application of an accepted method, and structure the threats section around its categories instead of inventing our own.
Direct, verifiable use in this study: rule 3 of the keyword derivation (§3.2), adherence to the mined ecosystem's native jargon dominates recall, comes from it, and it is what justifies tok/s, GGUF, and Q4_K_M in the matrix. The pretest recorded that omitting tok/s cost 100% recall on ggml-org/llama.cpp. The record of rejected terms (§3.2) also follows its replicability requirement.
Limits: a teaching text, not a result. It supports how the corpus was built, never a claim about inference cost.

Complementary methodological references (used, outside the PDF library)

ReferenceWhere it is used in this study
Islam, Nguyen, Pan, Rajan. A Comprehensive Study on Deep Learning Bug Characteristics. ESEC/FSE 2019Base protocol for the entire study: vocabulary derivation by symptom (§3.2), sample stratification by repository (§3.5), funnel table format (§4), entry-point taxonomy adapted from pipeline-stage stratification (§3.6)
Islam, Pan, Nguyen, Rajan. Repairing Deep Neural Networks: Fix Patterns and Challenges. ICSE 2020Supports the fix and regression terms in the keyword matrix; reference for the distinction between progressive and load-time exhaustion
Cohen. A Coefficient of Agreement for Nominal Scales. 1960Inter-annotator agreement statistic (§5.1)
Landis & Koch. The Measurement of Observer Agreement for Categorical Data. Biometrics, 1977Interpretation scale and the Kappa ≥ 0.61 acceptance criterion (§3.5)
Byrt, Bishop, Carlin. Bias, prevalence and kappa. J. Clin. Epidemiol., 1993PABAK and the prevalence and bias indices, which control for the Kappa paradox (§5.1)
Dantas Cruz, Paul, Song, Tilevich. STARGAZER. IEEE SMDS 2020The work v2 extends; defines the regression targets the keyword matrix has to cover (§3.2, rule 2)
Zou et al. EnerInfer: Energy-Aware On-Device LLM Inference. 2026Supports the energy-axis terms (battery, energy, power), which were run and whose negative result is reported in §5.6
What this set does not cover, and the risk that remains open

There still is no paper that defines the problem as a missing release step. This is the Phase 0 gate's finding and the reason the paper exists. None of the 11 papers predicts memory or thermal behavior across a device fleet, and this absence is the cleanest formulation of the contribution space.

Open risk: Kanyiki (AIware 2026, doi:10.1145/3805760.3814901), the abstract has not yet been obtained and the PDF has no known open access. It needs to be read before publishing the gap argument. It is the only known gap in the review.

Two honesty caveats about the reading

1. The numbers above came from abstracts and opening pages, not a full read with page-by-page checking. They are recorded in the group READMEs with that mark. None of them should go into the paper's final text without rechecking against the PDF, which applies especially to the claims we will use adversarially (CARB and Tu et al.), where an imprecise citation is fatal.

2. Seven of the 11 papers are 2026 preprints (arXiv, with no completed peer review). This is unavoidable given the topic's time window, but it needs to be stated: the "state of the art" against which the gap is measured is, in large part, unreviewed literature, and a reviewer may legitimately point this out.

§8Threats to validity and declared biases

Structured according to Codabux et al. (2025)'s categories. None of these items is a novelty discovered during review; all were measured during the pipeline and are recorded in the artifacts. The purpose of stating them is for the paper not to be surprised by them.

External validity: who the corpus applies to

V1 · Concentration in Apple Silicon

Of the 307 issues with a specific platform, 201 (65%) are Apple Silicon. The llama.cpp, ollama, and mlx communities are mostly Mac. Every conclusion about "on-device" is biased toward high-capacity unified memory, the opposite of the constrained Android/edge cohort. Comparison: Android 76 · iOS/iPhone 86 · Jetson 16 · Raspberry Pi 7.

Consequence: this is the study's most serious bias, because the overrepresented cohort is precisely the one that suffers least from memory pressure.

V2 · Concentration in two repositories

llama.cpp (330) + ollama (124) = 73% of retained issues. Declarable, and not fixable through sampling — the sample is proportional by construction, so it reproduces the imbalance instead of compensating for it. Fixing it would require disproportionate sampling, which would in turn bias the population frequencies.

V3 · GitHub only

Forums, Discord, r/LocalLLaMA, and app-store reviews are left out, and that is likely where the energy cost, absent here, is perceived and reported. Reinforced by the grid's empty papel:aplicativo cell (§3.1).

V4 · ROCm/ROCm absent

300 queries, HTTP 422, zero issues. The study has 11 repositories, not 12. Cause identified later: renaming to ROCm/legacy-rocm-build (§3.1). Pending: update TARGET_REPOS and recollect the repository.

Construct validity: whether we measure what we claim to measure

V5 · Mandatory numeric metric in the prose

Discards legitimate qualitative reports. It is the measured cause of the absence of the energy axis (§5.6) and of discarding llama.cpp#3422 despite its score of 17. This is the criterion to revisit if RQ1 is kept with the energy axis included.

V6 · The automatic entry-point classification was invalid

Already corrected and documented in §5.2, but remains a threat because the correction applies to 27 issues and the other 593 remain classified by the refuted heuristic. Any entry-point frequency over the 620 is invalid until labelling is extended.

V7 · The operational definition has a known, unamended ambiguity

"Attributable" vs. "reproducible" in condition 4, the cause of 5 of the 6 disagreements (§6.4). Needs a written amendment before the human round.

Internal validity: the temporal asymmetry, and why it is not an artifact

2026 issues are 34.6% of the raw corpus but 60.2% of the filtered one. The first hypothesis, that the filter favors the recent template format, was tested and rejected: the template's expectation section is more common in 2023 (19.3%) than in 2026 (7.4%), and the median score is flat across years.

The measured cause is different: the practice of reporting cost matured.

Indicator2023202420252026
Median prose (characters)9148199821,896
Numeric metric in the prose18.2%18.4%23.1%45.2%
Quantization mentioned24.7%27.3%35.0%52.1%
KV cache / context4.4%8.0%9.6%20.4%
Regression between versions2.5%3.7%6.2%20.2%
Specific hardware39.3%29.3%21.2%24.4%
Filter retention rate9.2%3.8%4.0%13.6%

In 2023 the reporter said "doesn't work on my Mac," which is why specific hardware is more frequent. In 2026 they say "Q4_K_M, 8k of context, 2× slower since build bNNNN, 70 °C."

V8 · Hard consequence for the study

Frequencies cannot be compared across years. Any observed difference would be a change in reporting practice, not in the problem's incidence. Every longitudinal claim in RQ2/RQ3 needs to state this confound, or be dropped.

Conclusion validity: sample size

V9 · n = 27 is small for the derived frequencies

The 95% CI for the 26% Artifact figure is ≈ 11%–46%. The structural findings are robust because they do not depend on classification: the backend lift, the median magnitude of 4×, the absence of the energy axis. The per-category frequencies are not, and should be reported with an interval or held back until labelling extends to the 620.

§9State of the deliverables and reproducibility

Done and verified

  • Repository selection protocol declared and executed against the API: funnel E0→E6 with 172 approved, context signal, A6 sensitivity, bias report, and blind screening protocol
  • Keyword matrix fully traceable: 26 terms, each with a justification and a reference; 5 rejections recorded; API constraints verified
  • Real collection with full provenance: 3,600 queries, 7,889 issues, two anomalies handled (truncation bisection, documented HTTP 422)
  • Filter v2 with a declared criterion, open weights, cutoff sensitivity analysis, and a frozen, reproducible v1 baseline for comparison
  • Stratified sampling with a fixed seed and Kappa milestones as an early-warning control
  • Complete funnel generated by script, end to end, including the per-repository table
  • Discard audit built, with strata, declared weights, and a recall formula fixed a priori
  • Reading library: 11 PDFs in 4 groups, with each paper's role in the written text

Pending, in priority order

  1. Amend the operational definition, "attributable" vs. "reproducible" (§6.4). Blocks everything downstream, because without it the human Kappa measures disagreement over the definition.
  2. Definitive human labelling round of the 60 issues, in parallel and independently (Tiago + Isaque/Breno). Replaces the Kappa and every frequency derived from it.
  3. Fill in the audit of 45 discards → first recall estimate. Today the study reports precision without recall.
  4. Human round of M1–M3 screening of the 172 approved repositories (E7) → decide whether the list of 11 holds or expands. The LLM pilot included 86, already under collection, but it does not replace this round.
  5. Update ROCm/ROCm to the resolved name, ROCm/legacy-rocm-build, in TARGET_REPOS (scripts/msr/common/repos.py).
  6. Recheck every literature number against the PDF before it enters the paper, with priority for CARB and Tu et al.
  7. Obtain and read Kanyiki (AIware 2026) before publishing the gap argument.
  8. Recalculate every frequency in results_analysis.md against the definitive labelled set.

Reproducibility

Every number in this report comes from a script-generated artifact. There are only three hand-written files (keyword_matrix.md, repository_matrix.md, annotation/PROTOCOL.md), and they are pipeline inputs, not outputs. The generated ones carry a "generated by script, do not edit by hand" banner at the top, because editing them would make the paper's number diverge from the dataset's number, which is exactly the problem build_funnel.py exists to prevent.

ArtifactWhat it contains
data/msr/README.mddata status, collection caveats, labelling spreadsheet schema, operational definition, acceptance criteria
data/msr/results_analysis.mdfull analysis of the 620 retained issues: descriptives, RQ1/RQ2/RQ3, magnitude, scope, biases, individual reading of the 12 best issues
data/msr/funnel_diagram.mdMermaid funnel, per-repository table, discard anatomy, dataset distribution
data/msr/kappa_report.mdKappa per milestone, diagnostics, confusion matrix, agreement per repository, disagreements, tiebreak procedure
data/msr/filter_v1_v2_comparison.mdwhy v1 was replaced, with the measurement that motivated each of the three changes
data/msr/discard_audit.mddiscard reasons, suspicion weights, strata, the 30 most suspicious discards, the lost energy axis
data/msr/top_issues.mdthe 40 top-scoring issues, with the reason for each, the page to check whether what the pipeline calls a "good issue" matches the advisor's judgment
data/msr/repository_selection.md · repository_validation.mdrepository funnel, context signal, A6 sensitivity, and retroactive validation of the current list, with the grid's empty cells
data/msr/selection_bias_report.mdtest for concentration in Apple and in app-role repositories, original list against derived list
data/msr/annotation/SCREENING_PROTOCOL.mdoperational definitions of M1–M3, agreement milestone at row 30, and the screening tiebreak procedure
data/msr/mining_provenance.jsoncollection provenance: timestamps, queries, and requests per repository, applied API limits
references/ + 4 group READMEs11 PDFs with each paper's role, evidence, and limits

The complete pipeline, from scratch:

pip install -r scripts/msr/requirements.txt
export GITHUB_TOKEN=...

python scripts/msr/00_selection/select_repos.py              # repository funnel
python scripts/msr/00_selection/bias_report.py               # bias of the derived list
python scripts/msr/00_selection/split_screening.py --limit 30 # blind screening spreadsheets
python scripts/msr/01_mining/mine_issues.py --dry-run     # validates the query plan
python scripts/msr/01_mining/mine_issues.py --fresh       # raw collection
python scripts/msr/01_mining/mine_issues.py --requery-truncated
python scripts/msr/02_filtering/filter_issues.py             # criterion v2 (default)
python scripts/msr/02_filtering/filter_issues.py --criterion v1   # reproduces the baseline
python scripts/msr/03_annotation/sample_for_annotation.py     # stratified sample
python scripts/msr/03_annotation/split_for_annotators.py      # two independent files
#   … manual labelling by the two annotators …
python scripts/msr/03_annotation/merge_annotations.py
python scripts/msr/04_agreement/calculate_kappa.py --strict  # agreement
python scripts/msr/02_filtering/inverse_filter.py --n 45     # discard audit
python scripts/msr/05_reporting/build_funnel.py              # funnel + tables

Without a token, make_synthetic_dataset.py generates a synthetic dataset to run the pipeline offline. select_repos.py --validate-current runs without a token (public API, 60 req/h).

§10Open questions, what needs deciding with the advisor

In this order, because the first blocks the others.

1 · Does condition 4 of the operational definition require attributability or reproducibility?
It is the cause of 5 of the 6 disagreements (§6.4), and tiebreak rule 4 already requires a written amendment. Concrete consequence: if the criterion is "reproducible," issues like llama.cpp#681 and #932 (hardware described only as "4 cores, amd, linux") drop out, and the measured precision falls from 45% to ~37%. If it is "attributable," they stay. Both are defensible; what is not defensible is starting the human round without deciding.
2 · Does RQ1 narrow to memory/latency/throughput, or is the filter fixed to admit the energy axis?
The 77 discarded thermal/energy-axis issues (§5.6) show the choice is real, not forced. Narrowing the RQ is more honest and cheaper; fixing the filter widens coverage but requires recollecting and refiltering. My inclination: narrow RQ1 and state the energy axis as future work with a different source (app-store trackers), because the root cause is the absence of the papel:aplicativo cell in the grid — that is, it is a repository-selection problem, not a filter problem.
3 · Is RQ2 reformulated as backend × platform?
The data are unambiguous (lifts of 31.0 against ~1.0) and the reformulated version is more actionable. The cost is that the RQ changes after seeing the data, which needs to be stated as such in the paper, not hidden. Specific question: do we state the original RQ2 with its negative result and the reformulated one with its positive result, or do we replace it?
4 · Does the list of 11 repositories hold, or does screening of the 172 become part of the study?
Holding is defensible with the retroactive validation document, but the claim stays at "the repositories satisfy declared criteria," not "the protocol selected them." Expanding fixes the Apple Silicon bias (the most severe, §8 V1) and fills empty cells, but costs a whole new collection: for the 86 from the pilot screening that is 26,058 queries, about 19 h of API time, plus refiltering. There is a middle path: add only repositories that fill an empty cell (papel:aplicativo, acelerador:qualcomm), keeping the current 11.
5 · Is the declarable scope of ~26% acceptable for the paper's framing?
Labelling reduced the predictor's reach from 69% to 26% (§5.2). This can be read two ways: as a weakening of the contribution, or as an honest delimitation that makes the contribution defensible. My reading: the second, and ollama#16051 (cold vs. warm, 60–400×) is the counterexample to cite by name, but I want to confirm this does not compromise the framing before writing the contribution section.
6 · Does the human labelling round cover 60 issues or get extended?
With 60, per-category frequencies have a wide CI (§8 V9) and the remaining 560 stay under the refuted heuristic. Extending to ~150 would make the frequencies reportable, at the cost of two annotators' time. Alternative: label the 119 issues with score ≥ 14 (88% precision), which are the core of the evaluation-instance set — this serves the benchmark even if it does not serve the population frequencies.