A published agent run. Projected days over 35 degrees by 2050, the share of land that is bushfire-prone and median household income, combined across every NSW federal electorate to find where the largest rise meets the lowest incomes.
Zenancy
This is one run, published the way it came out of the app. The report below, its figures, its captions and its notes on the data are the agent's own; nothing has been re-run to look better, and the calls that failed are shown where they happened.
The prompt
The prompt, as typed
›
For every NSW federal electorate, combine projected days over 35 °C by 2050 under the high-emissions scenario, the share of land that is bushfire-prone, and the average median household income. Which ten seats pair the largest rise in hot days with the lowest incomes? Table them with the sitting member, chart heat rise against income, and map all NSW seats by projected hot days.
This is a distributional question wearing a geography question's clothes. Each of the three measures is available on its own and none of them is published on an electorate: the heat projection is a climate model grid, the bushfire layer is a state hazard map, and the income is a census figure on statistical areas. Putting them on the same boundary and then asking which seats sit at the bad end of two of them at once is the whole job.
Ran a cell in the sandbox(46, 1.2233274995421153, 59.184871029427555, 3.8, 1216.0, 2942.0, 0)5.5s
Rendered a tableRendered `data_2` as a table (10 rows) titled "NSW federal seats with the largest heat rise and lowest incomes, 2050".
Rendered a chartRendered `data_1` as a scatter chart titled "NSW federal electorates: heat rise against household income" (46 rows).
Rendered a mapRendered `data_1` as a division region map titled "NSW federal electorates by projected days over 35 °C in 2050" (46 division areas).
Wrote the documentTOOL ERROR: block data_1 is placed more than once — place each block exactly once.failed
Ran a cell in the sandboxwritten
Rendered a chartRendered `data_3` as a scatter chart titled "NSW federal electorates: heat rise against household income" (46 rows).
Rendered a mapRendered `data_4` as a division region map titled "NSW federal electorates by projected days over 35 °C in 2050" (46 division areas).
Wrote the documentTOOL ERROR: this document is not publishable yet — 2 things to fix:failed
Wrote the documentTOOL ERROR: this document is not publishable yet — 1 thing to fix:failed
Wrote the documentRendered a report titled "NSW federal electorates: heat rise, bushfire-prone land and income" embedding 3 blocks: data_2 (table), data_3 (chart), data_4 (map). Their standalone copies from this turn h
3 calls failed and the agent recovered within the same run. Failures are shown because they happened.
What it produced
NSW federal electorates: heat rise, bushfire-prone land and income
Across all 46 NSW federal electorates, projected days over 35 °C rise by 1.2 to 59.2 days a year by 2050 under SSP5-8.5. Parkes has the largest rise at 59.2 days, while Cowper has the lowest seat average of SA2 median household incomes at A$1,216 a week. The ten-seat shortlist combines heat-rise and income ranks, not a published risk score.
Key findings
Parkes records the largest projected rise, 59.2 days over 35 °C by 2050, compared with the NSW electorate median rise of 3.8 days.
Cowper has the lowest seat average of SA2 median household incomes at A$1,216 a week, compared with the highest seat value of A$2,942.
The shortlist contains ten seats: Farrer ranks first on the combined ordering, while Parkes ranks first on heat rise alone at 59.2 days.
All 46 NSW seats have a bushfire-prone land share in this dataset, so the requested land measure is available for every seat rather than only a subset.
Heat rises most in inland seats, while the state-wide midpoint is 3.8 days
The projected rise ranges from 1.2 days in the least-affected NSW electorate to 59.2 days in Parkes, with a median of 3.8 days across all 46 seats. The table uses the model's 2050 SSP5-8.5 change in days over 35 °C, alongside the modelled 2050 level, so a large rise is not confused with the endpoint itself.
NSW federal seats with the largest heat rise and lowest incomes, 2050
Federal electorate
Sitting member
Party
Rise in days over 35 °C by 2050
Projected days over 35 °C in 2050
Bushfire-prone land (%)
Seat average of SA2 median household income (A$/week)
Heat-rise rank
Income rank
Combined rank
Farrer
Sussan LEY
Liberal
30.48
68.58
66.36
1,420
2
6
8
Parkes
Jamie CHAFFEY
The Nationals
59.18
115.06
86.59
1,424
1
8
9
New England
Barnaby JOYCE
The Nationals
24.18
33.75
87.99
1,338
4
5
9
Riverina
Michael McCORMACK
The Nationals
24.87
40.39
70.44
1,519
3
12
15
Calare
Andrew GEE
Independent
24.09
33.9
94.58
1,552
5
14
19
Page
Kevin HOGAN
The Nationals
8.54
10.71
98.28
1,277
16
3
19
Fowler
Dai LE
Independent
9.09
10.67
14.75
1,453
13
10
23
Hunter
Dan REPACHOLI
Australian Labor Party
14.16
17.5
94.11
1,631
9
17
26
Blaxland
Jason CLARE
Australian Labor Party
5.83
6.73
1.28
1,490
19
11
30
Chifley
Ed HUSIC
Australian Labor Party
14.2
16.8
38.47
1,899
6
25
31
Ten NSW federal electorates ranked by the combined heat-rise and income ranks, with sitting member, projected heat, bushfire-prone land and income · AEC electorate profile, NEX-GDDP-CMIP6 ACCESS-CM2 and 2021 Census-derived income measures · 2050
Lower incomes overlap with the largest heat changes
The income measure ranges from A$1,216 a week in Cowper to A$2,942 in the highest-income NSW electorate. The ten-seat shortlist ranks each electorate separately on heat rise and income, then adds the two ranks. It therefore identifies seats that perform poorly on both dimensions without assigning an invented weight to a hot day or a dollar.
NSW federal electorates: heat rise against household income
All 46 NSW federal electorates compared by projected heat rise and seat average of SA2 median household income; point size indicates bushfire-prone land share · 2050 SSP5-8.5
Bushfire exposure is a land measure, not a population measure
The bushfire-prone share is included for each of the 46 NSW electorates, and the comparison is between land shares rather than residents or households. The scatter retains the full electorate set so the relationship between heat rise and income can be read across the state, while point size carries the bushfire-prone land share. The map colours the same 46 seats by projected hot-day level, which is a different measure from the rise.
NSW federal electorates by projected days over 35 °C in 2050
All 46 NSW federal electorates shaded by projected days over 35 °C · AEC 2025 boundaries and NEX-GDDP-CMIP6 ACCESS-CM2 · 2050
The electorate map uses projected 2050 hot-day levels, not the rise from baseline. That distinction matters: an electorate can have a high 2050 level because its baseline is already hot, while another can have a larger change from a cooler baseline.
What it said
How it got there
Every cell the agent ran, in order and in full. A briefing that names seats had better show its working.
bashcell 1 of 2
python3 - <<'EOF'
import zn
con = zn.lake_con()
DIV = zn.read('electoral_boundaries', file='division_h3r9_aec2025')
PRJ = zn.read('climate_projections', file='projections_ssp585')
DP = zn.read('division_profile')
con.execute(f"""
CREATE OR REPLACE TEMP TABLE seat_climate AS
WITH r4 AS (
SELECT name AS division_name,
h3_cell_to_parent(h3_r9, 4) AS h3_r4,
count(*) AS r9_cells
FROM {DIV}
WHERE state = 'NSW'
GROUP BY 1,2
), p AS (
SELECT h3_r4, days_over_35, d_days_over_35
FROM {PRJ}
WHERE decade = 2050
)
SELECT r4.division_name,
sum(r4.r9_cells * p.d_days_over_35) / sum(r4.r9_cells) AS heat_rise_days_2050,
sum(r4.r9_cells * p.days_over_35) / sum(r4.r9_cells) AS heat_level_days_2050,
sum(r4.r9_cells) AS matched_r9_cells
FROM r4 JOIN p USING (h3_r4)
GROUP BY 1
""")
# materialise complete seat table and top ten separately
con.execute(f"""
COPY (
WITH j AS (
SELECT d.division_name,
d.member_given_name || ' ' || d.member_surname AS member,
d.member_party_name AS party,
c.heat_rise_days_2050,
c.heat_level_days_2050,
d.bushfire_cell_share_pct,
d.median_hh_income_weekly_avg,
rank() OVER (ORDER BY c.heat_rise_days_2050 DESC) AS heat_rank,
rank() OVER (ORDER BY d.median_hh_income_weekly_avg) AS income_rank,
rank() OVER (ORDER BY c.heat_rise_days_2050 DESC)
+ rank() OVER (ORDER BY d.median_hh_income_weekly_avg) AS combined_rank
FROM {DP} d JOIN seat_climate c USING (division_name)
WHERE d.state = 'NSW'
)
SELECT division_name,
member,
party,
heat_rise_days_2050,
heat_level_days_2050,
bushfire_cell_share_pct,
median_hh_income_weekly_avg,
heat_rank,
income_rank,
combined_rank
FROM j
ORDER BY combined_rank, heat_rank, division_name
) TO '/workspace/out/nsw_seats_all.csv' (HEADER)
""")
con.execute("""
COPY (
SELECT * FROM read_csv_auto('/workspace/out/nsw_seats_all.csv')
ORDER BY combined_rank, heat_rank, division_name
LIMIT 10
) TO '/workspace/out/nsw_seats_top10.csv' (HEADER)
""")
print(con.sql("SELECT count(*) AS seats, min(heat_rise_days_2050) AS min_rise, max(heat_rise_days_2050) AS max_rise, median(heat_rise_days_2050) AS median_rise, min(median_hh_income_weekly_avg) AS min_income, max(median_hh_income_weekly_avg) AS max_income, count(*) FILTER (WHERE bushfire_cell_share_pct IS NULL) AS bushfire_unassessed FROM read_csv_auto('/workspace/out/nsw_seats_all.csv')").fetchone())
print(con.sql("SELECT division_name, heat_rise_days_2050, median_hh_income_weekly_avg, combined_rank FROM read_csv_auto('/workspace/out/nsw_seats_top10.csv') ORDER BY combined_rank, heat_rank, division_name").fetchall())
EOF
bashcell 2 of 2
python3 - <<'EOF'
import duckdb
con=duckdb.connect()
con.execute("COPY (SELECT * FROM read_csv_auto('/workspace/data/data_1.csv')) TO '/workspace/out/nsw_seats_chart.csv' (HEADER)")
con.execute("COPY (SELECT * FROM read_csv_auto('/workspace/data/data_1.csv')) TO '/workspace/out/nsw_seats_map.csv' (HEADER)")
print('written')
EOF
What this run does not tell you
The report carries its own notes on the data, reproduced here exactly as the agent wrote them:
The heat rise and projected hot-day level are area-weighted over the electorate's mapped land cells after matching to the 2050 SSP5-8.5 projection grid. This is one climate-model run, not an ensemble or a forecast.
Income is a seat-level average of SA2 median household incomes from the 2021 Census interpolated onto 2025 electorate boundaries. It is not the median income of a household in the seat. Bushfire share is a share of land, not a share of residents.
Three things to add to them, none of which is specific to this run.
A high scenario is not a prediction. Projections under a high-emissions pathway describe one plausible world, and a count of days over a threshold is more sensitive to model choice than a change in average temperature is. Direction is robust; the number is not.
Bushfire-prone mapping is a planning trigger, not a risk score. The share of an electorate that is mapped says how much land sits inside a planning overlay. It does not say how often it burns, how severe a fire would be, or how many people live in the mapped part.
An electorate figure is an allocation. Income and population are published on statistical areas that an electoral boundary cuts through, and every seat-level figure here is those areas apportioned to the seat. Two defensible methods give slightly different answers, and the ranking of adjacent seats can turn on that.
Run it on your own boundaries
The state and the three measures are the ones the prompt named. The same combination runs over any set of electorates, council areas or statistical regions, and over any of the climate, hazard and demographic layers in the library. If you want to see it against yours, request access — or read how this is used for electorate analysis and by government and public affairs.