\section{Data extraction and variable harmonisation} \label{sec:extraction} \subsection{Extraction pipeline} Each retrieved PDF was processed with PyMuPDF to extract page text, and pages were scored for the density of coefficient-like patterns (decimals followed by parenthesised values or significance stars), table vocabulary and hedonic variable names; the candidate regression pages, with the first page and the abstract, were assembled into a compact dump per paper. Independent extractor agents then read the dumps, and the original PDF pages when tables were garbled or image-only, and produced a structured record per paper following a written protocol and a fixed JSON schema: study metadata (country, city, sample period, property type, price measure, document type, estimators, fixed effects, standard-error type, sample size, AI methods), one entry per model column (table, column, page, dependent variable and its transformation, estimator, sample size, fit, and what the parentheses contain) and one row per coefficient (printed variable name, taxonomy identifier, regressor transformation and unit, coefficient, standard error, $t$, $p$, stars, confidence interval, page, extraction confidence and notes). The rules were strict: only printed numbers; no inference of standard errors; standard errors printed as zero after rounding stored as missing; fixed-effect dummies, constants and interaction terms excluded or flagged; papers whose unit of analysis is an aggregate, whose data are simulated, or whose characteristic coefficients are not reported marked ineligible with the reason. Extractors assigned a confidence level to every row, and rows marked low, those whose numbers had to be guessed from context, are excluded from the primary synthesis. \subsection{Validation} A random sample of \valPapersDoubleExtracted{} eligible papers was re-extracted by a second, independent agent that had no access to the first extraction. The two extractions agree on eligibility for \valEligibilityAgreement{} percent of papers; among the \valCoefficientsCompared{} coefficient rows that could be matched on model, taxonomy and printed variable name, the coefficients agree to within one percent in \valBetaAgreementOnepct{} percent of cases, the standard errors in \valSeAgreementOnepct{} percent, the signs in \valSignAgreement{} percent and the taxonomy assignment in \valTaxonomyAgreement{} percent; recall and precision of the primary extraction relative to the duplicate are \valCoefRecall{} and \valCoefPrecision{} percent, the shortfall reflecting differences in which auxiliary variables (composite indices, planning-zone dummies, local-regression summaries) each extractor chose to record rather than disagreement on the hedonic variables themselves (Table~\ref{tab:validation}). \subsection{Taxonomy} Variables were mapped to a hierarchical taxonomy of \nTaxonomyLeavesObserved{} observed characteristics in eight groups: structural, interior amenities, exterior amenities, location and accessibility, environmental, neighbourhood and socioeconomic, market and transaction, and AI-derived (Table~\ref{tab:taxonomy}). Each leaf has a conceptual definition and a list of equivalent printed names; conceptually distinct variables (bedrooms versus total rooms, distance to a station versus distance to a railway line, waterfront versus distance to water) are kept separate, and variables with no leaf are recorded under ``other'' with their printed name so that the mapping can be audited. \subsection{Effect-size harmonisation} Coefficients were converted into effect-size families according to the dependent-variable transformation and the regressor's transformation and unit, with the formula stored for every row. For a binary regressor in a log-price model the primary family is the percentage premium $100[\exp(\hat\beta-\hat\sigma^2_\beta/2)-1]$, which applies the \citet{kennedy1981estimation} correction to the retransformation of \citet{halvorsen1980interpretation}, with delta-method standard error $100\exp(\hat\beta)\hat\sigma_\beta$; the uncorrected premium is kept as a sensitivity. For a continuous regressor in levels in a log-price model the family is the semi-elasticity $100\hat\beta$ per harmonised unit, after converting square feet to square metres, metres, feet and miles to kilometres, and recording the unit when it cannot be harmonised (minutes, indices, shares), in which case the row is excluded from the pooled analysis of that characteristic. Log-log coefficients form the elasticity family. Level-price coefficients form the monetary family, which is reported descriptively (signs and significance) but never pooled across currencies and price levels. Rows whose regressor is a construction year rather than an age, a standardised coefficient, a squared term or an interaction are flagged and excluded from pooling. Standard errors were recovered only from printed $t$-statistics, confidence intervals or exact $p$-values, with the recovery formula stored; stars-only and $p$-only tables therefore contribute to the descriptive synthesis but not to the inverse-variance pooling. Partial correlations $r=t/\sqrt{t^2+df}$ were computed for every row with a $t$-statistic as a unit-free secondary family. Of the \nCoefExtracted{} coefficient rows extracted from \nStudiesExtracted{} eligible studies, \nUsableEstimates{} are usable in the primary pooled synthesis after these filters. {\scriptsize\input{tables/tab04_taxonomy_long}} \begin{table}[H] \centering \caption{Extraction validation on the independent double-extraction sample} \label{tab:validation} \small \input{tables/tab12_extraction_validation} \end{table}