Repository navigation
fix(harness): name a share's named members as its whole where the numerator holds others - #85
Merged
Merged
Conversation
…s plan "What share of ODA to Kenya came from the United States?" divides by official donors (DAC) in some runs and by all providers in others, and neither the card nor the approved plan said which. make_charts now writes the whole into a share card's title from the denominator's selected source, as it writes the period, and the plan's fetch label and share sentence name the group or member count that source holds in place of "every donor".
A denominator filtered by value or cut to its top members before its total still read "of the total from all 140 donors"; a per-period rank writing positions carried the share's whole; and the whole a numerator also holds was matched by wording. share_wholes now names no whole past a narrowing step, stops at a step whose output is not a ratio, and compares populations by group ref or axis and member count. The plan's share sentence names the narrowing step in place of the parties.
A plan said "Uganda and all 108 donors" and "summed over its 288 indicators" while the answer said 92 providers with data in 2022 and 13 indicators, with nothing to tie the two. The plan now says "the 108 donors the source holds in any year" and "summed over whichever of its 288 indicators hold data", a share card's whole names an open axis with no count, and the orchestrator instruction quotes the new phrases.
…guess
The plan's donor count is already the providers with data in the plan's
years (and, with dfo-apis counting parties only, the donors the frame
holds), so "the N donors the source holds in any year" was false; it
reads "all N donors" again. The indicator clause states Search's exact
count of indicators with data where every entity axis is named
("summed over its 13 indicators"), and the family size otherwise. A
flow side's count comes from role_axis_facts over the scope list's
length, and the orchestrator instruction says what each count counts.
…erator holds others
…re's whole A numerator narrowed to one entity now holds what its own input's sources hold, with that entity on the column its requirement names it under (side_entities), in place of assuming the denominator's frame. A share of the US out of UK and US ODA to Kenya, divided by the two donors' ODA to Kenya and Uganda, now names the recipients too.
Two open populations are the same only when their sources are one dataset, since sources record counts and no members; a different dataset of as many donors keeps its clause. A denominator reduced by a mean, maximum or minimum names no total, and neither does one narrowed to one entity. A card title keeps its whole only where the whole subject fits beside it in 120 characters; otherwise the whole goes in the card's note.
… fix/plan-counts-say-what-they-count # Conflicts: # services/harness/src/harness/plan_display.py # services/harness/tests/test_plan_display.py
…enominator's entity ai#79 now gives no whole for a denominator narrowed to one entity. Here both sides of a share narrow alike (_side_populations): the narrowed entity sits on its column (_narrowed_entity) and the input's other populations stay, so the United Kingdom's row of a two-donor frame reads "from United Kingdom". Named populations take a string-tuple identity, as open axes now do.
jm-rivera
changed the base branch from
fix/plan-counts-say-what-they-count
to
dev
October 26, 2026 14:53
…and-named # Conflicts: # services/harness/src/harness/plan_display.py # services/harness/tests/share_plan.py # services/harness/tests/test_plan_display.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A share whose denominator names its members gets no whole on its card. "What share of the United Kingdom's and the United States' ODA to Kenya came from the United States?" divides the US figure by the two donors together, yet the card title names only the period, so the reader cannot tell the share from the US share of all aid to Kenya. ai#79 names a whole only for named sets (DAC countries, G7) and for open axes; a column holding entities the question lists by name had no population and no entry in
_populations.This change gives such a column a population.
_named_entitiesinservices/harness/src/harness/plan_display.pyresolves each named entity through the denominator's source (resolve_name) and identifies the column by its sorted graph refs, worded byentities_phrase. A name that a set of the source answers (resolve_group) stays the set's population, as before. If any name resolves to nothing, the dataset gives no named population, since the column is then unknown._divided_wholenames a named column off the share axis only where the numerator is known to hold other entities there by identity. The numerator's own sources say what it holds. When it narrows one entity out of its frame (RequirementSide.entity),_narrowed_entityputs that entity on the column its requirement names it under (side_entities), and the frame's other columns stay as its sources hold them. A column both sides hold the same way is left out, so Kenya drops out, and the card reads "from United Kingdom and United States" in both plan forms: a separate US retrieval, or the US narrowed out of the two-donor frame. Both sides narrow alike (_side_populations), so a denominator taking the United Kingdom's row of a two-donor frame reads "from United Kingdom"; ai#79 gives such a share no whole. A side narrowed to an entity its sources do not resolve to one ref has no population: the denominator then names no whole, and the numerator shows nothing to compare. A list of names too long for the 120-character title goes to the card's note, as ai#79 does for any whole. On a pooled axis the existing rule holds, and ai#79's narrowing (_reads_whole) and ratio (_keeps_shares) rules apply to named columns as well.Names keep the requirement's words with no article ("United Kingdom", not "the United Kingdom"). Neither the graph's labels nor
planner.phrasingholds an article rule for place names, and adding one belongs with the phrasing helper, not with this change.Frames kept from an earlier run of the plan call need no whole.
_kept_asks(graph/execute.py) runs only on a stopped outcome and keepspresentable_steps, which drop every derivedops_frame (graph/answer.py), so a kept entry holds retrieval frames only, andshare_wholesgives a retrieval step no whole.This builds on ai#81 and should merge after it.
Testing:
test_a_share_of_named_donors_names_them_where_the_numerator_holds_othersintests/test_plan_display.pyhas seven rows over a newNAMED_DONORSsource intests/share_plan.py.named_donorsandnarrowed_out_of_the_framecover both plan forms.narrowed_out_of_another_framenarrows the US out of UK and US ODA to Kenya and divides by the two donors' ODA to Kenya and Uganda, expecting the recipients named too;named_on_both_sidesnarrows out of a frame holding the United States as donor and recipient. Both fail when the numerator is assumed to hold the denominator's frame.same_donorandsame_refname the numerator's donor in the denominator, the second as "USA", and expect only the recipients named.value_filterfilters donors to at least $1bn and expects no whole.test_a_denominator_narrowed_to_one_entity_names_that_entityexpects "to every recipient and from United Kingdom" for the United Kingdom's row of a two-donor frame.ruff check,ruff format --checkandty check srcare clean, and the full harness suite passes excepttest_server.py's zero-tools check, which fails locally only because a proxy listens on port 8083.