docs: separate the terms we own from the terms the services own - #405
Merged
thodson-usgs merged 5 commits intoSep 1, 2026
Merged
Conversation
Review of DOI-USGS#396 found `CONTEXT.md` using *tier* in its own prose without defining it. The word was there before that record was written; recording each explanation once made the gap visible rather than creating it. Fixing the one word would have left the reason it got there. The glossary is one flat list, and every place the code disagrees with it is filed under *Known legacy names* -- a heading whose framing is that the disagreement is debt. For most of the glossary that is right. For a few terms it is wrong, and being wrong about those has produced the same argument repeatedly: may a docstring say *site*, may `service=` name a collection, is prose about NWIS bound by a word taken from the Water Data API. The two sets differ in who has authority over them. *chunk*, *page*, *fan-out*, *plan*, *interruption*, *dialect*, *leaf* appear in no USGS API's vocabulary. They were invented here for machinery this package owns. Nothing outside constrains them, so spelling one of them three ways -- the resolution chain's layers have been a source, a tier and a rung -- is an inconsistency that can be removed by deciding, and should be. *monitoring location* and *collection* are not like that. The services name those things and disagree: `site_no` in NWIS, `Station` in WQP, `monitoring_location_id` in Water Data, a `sites` collection in NGWMN. No decision here reconciles them. A caller who read WQP's documentation looks for `Station`; an adapter that renamed it would be harder to use, and the parameter is public surface besides. One rule over both forces a choice between losing the glossary, and with it the vocabulary that lets transport and the OGC engine be written once, or enforcing it onto every adapter's public surface. So: ADR 0013 records the split. Core terms take one spelling everywhere, identifiers included, and a second spelling is a defect. Domain terms fix one word for prose while each adapter keeps its service's spelling in its parameters -- which is the adapter doing its job, not debt. `CONTEXT.md` follows. The preamble names the two kinds. *Monitoring location* and *collection* carry their per-service spellings in their own entries rather than as exceptions at the end. *Known legacy names* keeps only core-term spellings. And the package-wide **source** is called that, in the sentence that had called it a tier. This also settles what DOI-USGS#400 is. Renaming the configuration chain's `tier` to `source` looked discretionary while the glossary bound only prose; the chain is core machinery, so one spelling binds its identifiers too. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JAEQqs7XzQHGQQi2KakuXD
The glossary's Source entry claimed ADR 0010 calls a source a tier and ADR 0011 a rung. Neither is true. ADR 0009 and 0010 already say source -- source-major precedence is 0010's own phrase. 0010's tier names a different axis, the scope: the top-level tier that survives, the deferred gateway tier. 0011's rung is one position of its seven-rung ladder, where sources and scopes interleave. The code's tier-for-source identifiers misapplied 0010's scope word, and the glossary projected that confusion back onto the records; ADR 0013's standing example repeated it. Correcting the history also surfaced what was missing: Scope had no entry, though ADR 0010's whole subject is scoping, and the axis mixup is exactly the confusion a definition prevents. The Adapter-scoped setting entry carried the same error in the other direction -- "does not replace the package-wide source" named a scope level a source -- so the sentence now names the value rather than either axis. Also from this pass: portal is defined as the human-facing site fronting a service rather than left as an undefined near-synonym (CONTRIBUTING now says service where it meant the module split); the stall-timeout bullet no longer invites new prose to use either spelling; Facade is grounded in the design pattern it is named for; and the Source entry points NLDI's data_source at the domain-term rule. The preamble's define-before-use rule is restated without the ordering claim two mutually-referencing axes cannot satisfy. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JAEQqs7XzQHGQQi2KakuXD
thodson-usgs
added a commit
to thodson-usgs/dataretrieval-python
that referenced
this pull request
Sep 1, 2026
The glossary now defines the precedence ladder and its rungs (PR DOI-USGS#405), which makes the one identifier still saying "tiers" for ladder positions a core-term misspelling rather than a stray. The file's own comments already say rung. ADR 0011's compliance citation is annotated the way ADR 0008 annotated the wateruse rename, so the reference stays true. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JAEQqs7XzQHGQQi2KakuXD
ADR 0011, the user guide, and the configuration tests' comments all say rung; a word in use across three venues has earned its definition. With rung defined, the user guide's one "tiers below" was a second spelling of it and now reads "rungs below". Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JAEQqs7XzQHGQQi2KakuXD
Defining *portal* as the human-facing site created three problems it did not solve. The word already carries three unrelated senses here: WQP's proper name (the Water Quality Portal), anyio's blocking portal in transport/fanout.py, and the user guide's page title for a table of websites. The new definition made five existing wqp.py docstrings violations -- "the portal serves the legacy and WQX3 interfaces from one root" is about the service, and reads naturally precisely because that service is named Portal. A glossary entry that manufactures violations in correct prose is not carrying its weight. The CONTRIBUTING change it came with stands on its own: modules are grouped by service, which is what the Services section enumerates, and "data portal" maps to neither the modules nor the portal table cleanly. The architecture interface view said the same thing and now matches. ADR 0001 keeps its wording, being accepted. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JAEQqs7XzQHGQQi2KakuXD
8 tasks
AGENTS.md's first bullet said "when a term there conflicts with a name in the code, the term wins" -- the rule in its pre-0013 absolute form. That sentence is load-bearing: it is the entry point every agent and contributor reads before writing anything, and read literally it licenses renaming an adapter's public parameters to match the glossary. It did exactly that here, producing a rename that had to be reverted. ADR 0013 splits the rule, so the bullet now does too: a core term binds identifiers, a domain term binds prose only and each adapter keeps its service's spelling. The two examples are the ones reviewers keep asking about. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JAEQqs7XzQHGQQi2KakuXD
thodson-usgs
added a commit
to thodson-usgs/dataretrieval-python
that referenced
this pull request
Sep 2, 2026
One conflict, in CONTEXT.md's **Origin label** entry, which DOI-USGS#405 and this branch both rewrote. Kept both, as this PR's description proposed: DOI-USGS#405's `*Core terms.*` marker and its first sentence, which ADR 0013 now requires of every entry, followed by this branch's statement that the code matches. DOI-USGS#405's sentence calling the `tier`/`source` identifiers "a defect to correct" is dropped -- this branch corrects it. DOI-USGS#405's additive **Precedence ladder** entry is kept verbatim. The rest merged clean. DOI-USGS#405 had already changed the user guide's line 319 from *tiers* to *rungs*, which does not overlap this branch's line 437.
thodson-usgs
added a commit
to thodson-usgs/dataretrieval-python
that referenced
this pull request
Sep 2, 2026
`BaseConfiguration.load` said a profile still inherits the adapter's
default profile and the package-wide keys "from the sources below". Those
two are rungs 4 and 5, both inside the *file* source, so the sentence names
positions rather than categories -- exactly what CONTEXT.md reserves *rung*
for ("prose that means a whole category says source, reserving rung for
when the position itself matters"). The user guide states the same claim as
"the rungs below" since DOI-USGS#405, so the two now agree, as does ADR 0011's own
"each level overrides the one below".
Also joins the "apiece." the ladder sentence left orphaned on its own line.
thodson-usgs
added a commit
to thodson-usgs/dataretrieval-python
that referenced
this pull request
Sep 2, 2026
The glossary now defines the precedence ladder and its rungs (PR DOI-USGS#405), which makes the one identifier still saying "tiers" for ladder positions a core-term misspelling rather than a stray. The file's own comments already say rung. ADR 0011's compliance citation is annotated the way ADR 0008 annotated the wateruse rename, so the reference stays true. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JAEQqs7XzQHGQQi2KakuXD
thodson-usgs
added a commit
to thodson-usgs/dataretrieval-python
that referenced
this pull request
Sep 2, 2026
One conflict, in CONTEXT.md's **Origin label** entry, which DOI-USGS#405 and this branch both rewrote. Kept both, as this PR's description proposed: DOI-USGS#405's `*Core terms.*` marker and its first sentence, which ADR 0013 now requires of every entry, followed by this branch's statement that the code matches. DOI-USGS#405's sentence calling the `tier`/`source` identifiers "a defect to correct" is dropped -- this branch corrects it. DOI-USGS#405's additive **Precedence ladder** entry is kept verbatim. The rest merged clean. DOI-USGS#405 had already changed the user guide's line 319 from *tiers* to *rungs*, which does not overlap this branch's line 437.
thodson-usgs
added a commit
to thodson-usgs/dataretrieval-python
that referenced
this pull request
Sep 2, 2026
`BaseConfiguration.load` said a selected profile inherits the adapter's default profile and the package-wide keys "from the sources below". Both sit inside the file source -- rungs 4 and 5 -- so the sentence names positions, which is what CONTEXT.md reserves *rung* for. The user guide has said "the rungs below" since DOI-USGS#405; the two now agree. Also joins the "apiece." the ladder sentence left orphaned on its own line.
thodson-usgs
added a commit
that referenced
this pull request
Sep 2, 2026
* refactor: one word per concept in the configuration chain `_resolve` returned `(raw, source, tier)`: `source` held the exact origin (`$API_USGS_RETRIES`, a path to the config file) and `tier` held the ordered category CONTEXT.md calls the source. One word, two grains, in one signature. It now returns `(raw, label, source)`. The category takes the glossary's name, and the origin string takes `label` -- the name `_show_adapter_overrides` already used for it, and the one `_parse_int` documented as "Human-readable origin". Renamed to match: `_source_label` to `_origin_label`, `_env_source_label` to `_env_label`, and `BaseConfiguration._source` to `._label`; all three build an origin label, none names a source. The rename is mechanical: applied to the parent's AST with docstrings stripped, it reproduces this commit's AST exactly, for both modules. `show_configuration()`'s output stays byte-identical. The `show_configuration` docstring and the user guide said "source" for what is an origin label; both now say origin. CONTEXT.md drops the paragraph recording that the code spelled the pair backwards. Left for the pull request: the package still says "service" in places where the glossary's term is "adapter", including the printed `"<service default>"`. Each site needs its own judgement, and that one changes user-visible output. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JAEQqs7XzQHGQQi2KakuXD * docs: fix the wording the rename got wrong The rename proved behaviour unchanged by comparing ASTs with docstrings stripped -- silent, that is, about exactly the text a rename most easily breaks. Reading the diff found three kinds of damage: Breakage: `\bsource\b` had matched inside "source label", leaving "a label label" in `_resolve`'s summary and Returns section, and the summary still said "tier". Category errors: three sentences got "source" where the glossary means scope -- the file's adapter-scoped and package-wide lookups are two scopes within one source, not two sources. Leftovers: `tier` survived in `waterdata/configuration.py` and in four test docstrings the rename never covered; `_configuration_core` counted "three sources" where its module docstring numbers four, and dropped a preposition; and `WaterdataConfiguration` said "this service" and "every other adapter" for one thing in one sentence -- the scope is the adapter. Prose only; the AST comparison against upstream/main still holds. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JAEQqs7XzQHGQQi2KakuXD * test: call the ladder positions rungs, as ADR 0011 does The glossary now defines the precedence ladder and its rungs (PR #405), which makes the one identifier still saying "tiers" for ladder positions a core-term misspelling rather than a stray. The file's own comments already say rung. ADR 0011's compliance citation is annotated the way ADR 0008 annotated the wateruse rename, so the reference stays true. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JAEQqs7XzQHGQQi2KakuXD * docs: say rung where the ladder is meant, not scope Two docstrings called a rung a scope. The module docstring said ADR 0011 splits three of the four sources "into the scopes they contain", but the block source's split -- a passed instance vs a profile loaded from the file -- is the same scope either way. It now counts the ladder plainly: seven rungs over four sources, three of which hold two apiece. And the renamed test's docstring said a profile "replaces keys, never whole sources", where what it does not replace wholesale is the rung. Both wordings predate the glossary's scope/rung split; this PR owes them one word per concept. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JAEQqs7XzQHGQQi2KakuXD * docs: name the rungs a selected profile inherits from `BaseConfiguration.load` said a selected profile inherits the adapter's default profile and the package-wide keys "from the sources below". Both sit inside the file source -- rungs 4 and 5 -- so the sentence names positions, which is what CONTEXT.md reserves *rung* for. The user guide has said "the rungs below" since #405; the two now agree. Also joins the "apiece." the ladder sentence left orphaned on its own line. --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Why
Reviewing #396, @ehinman wrote:
The specific defect is real:
CONTEXT.mdused tier in its own prose andnever defined it. It also predates #396 —
"it does not replace the package-wide tier"was already there before that record was written. Recordingeach explanation once made the gap visible rather than creating it.
Fixing the one word would have left the reason it got there. This is the third
review round in a row to land on the same seam, so this PR addresses the seam.
The actual problem
CONTEXT.mdis one flat glossary, and every place the code disagrees with it isfiled under Known legacy names — a heading whose framing is that the
disagreement is debt. For most of the glossary that is right. For a few
terms it is wrong, and being wrong about those keeps producing the same
argument: may a docstring say site, may
service=name a collection, is proseabout NWIS bound by a word taken from the Water Data API.
The two sets differ in who has authority.
Terms we invented.
chunk,page,fan-out,plan,interruption,dialect,leaf— measured, these appear in zero USGS API vocabularies.Nothing outside constrains them, so a second spelling (the resolution chain's
code said tier where ADRs 0009 and 0010 say source; 0010's tier is the
scope axis and 0011's rungs are ladder positions) is an inconsistency
removable by deciding.
Terms the services own. These do not reconcile:
site_no,sites=Station,siteidmonitoring_location_idsitescollectionservice=Result,StationcollectioncollectionA caller who read WQP's documentation looks for
Station. An adapter thatrenamed it would be harder to use, and the parameter is frozen public surface
besides.
One rule over both sets forces a choice between two bad outcomes: abandon the
glossary, and the shared modules lose the vocabulary that lets transport and the
OGC engine be written once; or enforce it everywhere, and every adapter's public
surface drifts from the API it wraps.
That is the tension this PR names rather than keeps re-arguing.
What changed
ADR 0013 records the split and the two rules that follow it.
second spelling is a defect, not a variation.
service's spelling in its parameters. That is the adapter doing its job, not
debt.
CONTEXT.mdfollows:their own entries, instead of as exceptions at the end;
a tier.
What this settles
The recurring review question now has an answer that does not depend on who is
reviewing. In
nwisa docstring may say site — that is its service'sspelling and its parameters'. In
transportit may not, because nothingthere is about NWIS.
It also settles what #400 is. Renaming the configuration chain's
tiertosourcelooked discretionary while the glossary bound only prose; the chain iscore machinery, so one spelling binds its identifiers too. #400 stops being a
preference and becomes the rule applied.
Verification
1139 tests pass, including
test_adr_references_resolve_to_a_record, whichcovers the new
ADR 0013citations inCONTEXT.md. ADR 0013 parses clean asRST. Documentation only — no code changed.
I also checked the new preamble rule against the document itself: the remaining
undefined-looking words (
tier,rung,budget) are all the cross-referenceform the ADR explicitly permits, and
cursor/scopeare plain English ratherthan package vocabulary.
🤖 Generated with Claude Code
https://claude.ai/code/session_01JAEQqs7XzQHGQQi2KakuXD