Skip to content

About capability parity

Two libraries now answer to one name. That is the point of the unification, and it is also its sharpest risk. Once both are called idfkit, a reader who finds something in Python and not in JavaScript has no way to tell whether they have met a deliberate boundary or a defect, and the reasonable assumption is defect.

The parity ledger removes the guesswork. Every public capability of either library appears on it exactly once, with its availability in both languages, and every absence is described rather than left to be discovered. A written-down absence is documentation. An undocumented one is a bug report waiting to be filed against behaviour that is working as designed.

This page is the reader-facing view of that ledger. Everything below the generated marker comes from governance/parity.toml in the conformance repository, read at the immutable governance tag this release pins, so the page you are reading and the file both libraries' CI gates read cannot disagree. For the vocabulary side of the same governance, which name each concept carries in each language, see the naming map.

Three states, not two

A capability is complete, partial, or absent in each language.

The middle state is the one that earns its keep. A capability that exists in both languages and behaves differently is neither present nor absent, and calling it present is precisely the lie this ledger exists to prevent. Anything recorded as partial carries a description of what differs, because partial with nothing said about it is indistinguishable from complete.

Two kinds of absence

An absence alone tells you almost nothing. What you need to know is whether to wait or to plan around it, so every absent side is recorded as one of two kinds.

  • Not yet. The second language could have this and does not have it today. The entry names the issue tracking the port. Expect this to change.
  • Never. The capability is permanently single-language, and the entry says why. A permanent record is a stronger claim than a temporary one, so moving a capability out of never takes a constitutional amendment rather than an edit to the ledger.

On the page, a temporary gap is an amber notice naming a tracking issue and a permanent one is a plain notice naming a reason. In the table at the top, the same distinction reads as absent (not yet) against absent (never).

One entry per mechanism

Where the two libraries do something recognisably similar by fundamentally different means, that is two capabilities and not one.

Simulation is the case that forces the rule. Python drives a locally installed EnergyPlus through a subprocess; JavaScript runs a WebAssembly build in the browser. Recorded as a single simulation entry, whichever language the entry was written from would make the other read as deficient, and every page describing it would print a gap notice for a capability that is not missing. Visual output splits for the same reason: a static vector image drawn once is not a real-time rendered scene.

So local-simulation and browser-simulation appear separately, as do svg-visualisation and scene-rendering. Neither pair is ever collapsed. When you read one of them as Python-only or JavaScript-only, its partner entry is where the other language's answer lives.

The ids are load-bearing

Each capability's ledger id is a permanent public identifier, and it does three jobs at once. It is the anchor on this page, so a link to #local-simulation keeps resolving. It is the argument the parity() macro takes on every page that describes the capability, which is how availability reaches the point of use instead of living only here. And it is what the gates in both libraries match their exported surface against.

Ids get added and deprecated. They do not get renamed.

Generated from governance/parity.toml at governance-2026.22, the governance tag this release pins. Correct the ledger and regenerate; a correction made on this page would be overwritten, and it would never reach either library's CI gate.

Every capability at a glance

35 capabilities, counted by availability and then listed in full. Follow a capability to read what differs where the two libraries differ, and whether an absence is temporary or permanent.

Availability Python JavaScript
complete 31 16
partial 1 3
absent, not yet 0 11
absent, never 3 5
Capability Tier Python JavaScript
Reading IDF and epJSON 1 complete complete
Writing IDF and epJSON 1 complete complete
Documents, collections, and objects 1 complete complete
Reference graph 1 complete complete
Schema access and the version registry 1 complete complete
Model validation 1 complete complete
Describing an object type from the schema 1 complete complete
Building EnergyPlus documentation URLs 1 complete complete
Static types generated from the schema 1 partial complete
Diagnostics from an IDF parse 1 complete complete
The weather station index 1 complete partial
Retrieving weather and design-day files 1 complete partial
Declaring the conformance level a release passes 1 complete complete
Geocoding a place name 1 complete complete
Formatting-preserving round-trip 2 complete complete
Reading geometry from a model 2 complete partial
Building and transforming geometry 2 complete absent (not yet)
Intersecting and matching surfaces 2 complete absent (not yet)
Generating zoned blocks from a footprint 2 complete absent (not yet)
Construction thermal properties 2 complete absent (not yet)
Schedule evaluation 2 complete absent (not yet)
Reading the output variable dictionary and selecting variables 2 complete absent (not yet)
Design days and ASHRAE sizing conditions 2 complete absent (not yet)
Forward-migrating a model between EnergyPlus versions 3 complete absent (not yet)
Command-line interface 3 complete absent (not yet)
Checking source against another EnergyPlus version's schema 3 complete absent (not yet)
Plotting simulation results 3 complete absent (not yet)
Running a locally installed EnergyPlus and reading its results permanent complete absent (never)
Running EnergyPlus in the browser permanent absent (never) complete
Rendering a model to a vector image permanent complete absent (never)
Rendering a three-dimensional scene permanent absent (never) absent (never)
eppy compatibility surface permanent complete absent (never)
Caching retrieved weather files on disk permanent complete absent (never)
Language service for IDF text permanent absent (never) complete
Reading an EPW weather file 2 complete complete

Tier 1: the shared core

Both libraries carry these, and both are expected to keep carrying them. A difference you meet inside this tier is either stated below or a bug, and there is no third possibility.

Reading IDF and epJSON

Python complete · JavaScript complete · Tier 1 · ledger id parse

Vocabulary this capability owns in the naming register
  • parse IDF from a string
  • parse epJSON from a string
  • read IDF from disk
  • read epJSON from disk
  • the parse error type
  • detect a document version
  • an epJSON document value
  • read IDF from disk, keeping diagnostics
  • detect an epJSON document version

Writing IDF and epJSON

Python complete · JavaScript complete · Tier 1 · ledger id write

Vocabulary this capability owns in the naming register
  • serialize IDF to a string
  • serialize epJSON to a string
  • write IDF to disk
  • write epJSON to disk
  • serialize a document to an epJSON value
  • serialize one object

Documents, collections, and objects

Python complete · JavaScript complete · Tier 1 · ledger id document-model

Vocabulary this capability owns in the naming register
  • the document class
  • the collection class
  • the object class
  • an extensible group
  • create a new document
  • add an object
  • remove an object
  • rename an object
  • every object of a type
  • untyped collection access
  • one object, or nothing
  • one object, or an error
  • collection to a sequence
  • an object's type name
  • version

Reference graph

Python complete · JavaScript complete · Tier 1 · ledger id references

Vocabulary this capability owns in the naming register
  • the reference graph
  • objects referencing a name
  • a reference edge

Schema access and the version registry

Python complete · JavaScript complete · Tier 1 · ledger id schema-access

Vocabulary this capability owns in the naming register
  • load a schema for a version
  • the supported version list
  • resolve a version string
  • one version's schema
  • the difference between two schema versions
  • resolve the schema for a detected version
  • the process-wide schema source

Model validation

Python complete · JavaScript complete · Tier 1 · ledger id validation

Vocabulary this capability owns in the naming register
  • validate a document
  • validate an object
  • validation result
  • validation finding
  • validation severity

Describing an object type from the schema

Python complete · JavaScript complete · Tier 1 · ledger id introspection

Vocabulary this capability owns in the naming register
  • describe an object type
  • object description
  • field description

Building EnergyPlus documentation URLs

Python complete · JavaScript complete · Tier 1 · ledger id documentation-urls

Vocabulary this capability owns in the naming register
  • resolved documentation URL
  • documentation URL for an object type
  • I/O reference URL
  • engineering reference URL
  • documentation search URL

Static types generated from the schema

Python partial · JavaScript complete · Tier 1 · ledger id generated-object-types

What differs, and why

Coverage differs, and the difference is visible to anyone not on the newest release. The Python stub set is generated for one EnergyPlus version at a time and is currently shipped for 26.1.0 only, so a model loaded at 9.4 gets the 26.1 field names and choice lists from the editor. The TypeScript type maps are emitted per version and selected by the caller, who parameterises the document with the map for the version being read, so an older model is typed as that older model or is left untyped rather than mistyped.

Application differs too. Python's stubs apply implicitly to every document. TypeScript's are opt-in by construction: an unparameterised document stays untyped, which is what version-generic code needs.

Vocabulary this capability owns in the naming register
  • generated object types
  • a version type map

Diagnostics from an IDF parse

Python complete · JavaScript complete · Tier 1 · ledger id parse-diagnostics

Vocabulary this capability owns in the naming register
  • a parse diagnostic
  • diagnostics from a parse
  • recoverable diagnostics from a parse
  • a document and its parse findings

The weather station index

Python complete · JavaScript partial · Tier 1 · ledger id weather-index

What differs, and why

Installation differs, and the difference is deliberate. pip install idfkit installs weather and its station index unconditionally, because Python extras gate dependencies rather than files, so a Python reader has weather whether or not they wanted it. npm install @idfkit/idfkit installs neither: weather is an opt-in peer there, added with npm install @idfkit/weather. Both libraries ship their own index once installed and neither retrieves one to get started (FR-043, FR-075, research R11). A JavaScript reader who follows a weather page without installing that package gets a resolution error, not a smaller feature, which is why the packaging is recorded here as a stated difference rather than left as an undescribed detail.

Freshness handling differs. Python fires a throttled nudge from StationIndex.load(): at most once every 24 hours it probes the upstream KML files, warns when the bundled or cached index is behind, records the check under the cache directory, and can be turned off with IDFKIT_NO_WEATHER_UPDATE_CHECK. JavaScript has no such nudge and no timestamp to throttle against. It exposes checkForUpdates and refreshStationIndex for a caller who asks, and does nothing on its own, because the nudge is built on a writable cache directory and a browser-targeted package has none. The consequence for a reader is concrete: a stale index goes unmentioned in JavaScript until they check for themselves.

The installation difference above is the whole weather surface's, not the index's alone. It is stated here because the index is where a reader meets it first, and weather-download and weather-file-cache refer back to it rather than repeat it.

Vocabulary this capability owns in the naming register
  • the station index
  • search stations
  • a weather station
  • refresh the station index
  • a text search result
  • a proximity search result
  • which field a text search matched
  • the station wire record
  • the upstream index base URL
  • fetch a prebuilt station index
  • parse a KML station index
  • read station metadata from a download URL
  • great-circle distance between two points
  • the weather options-object types
  • the station index wire form
  • build an index from index data
  • the upstream index file list
  • the bundled station index
  • check the station index for updates

Retrieving weather and design-day files

Python complete · JavaScript partial · Tier 1 · ledger id weather-download

What differs, and why

Both libraries retrieve a station's ZIP archive from climate.onebuilding.org and unpack the EPW, DDY, and STAT members out of it. What they hand back differs, and it differs in the first line a reader writes. Python's WeatherDownloader.download returns a WeatherFiles whose epw, ddy, stat, and zip_path are Path objects, because the files are on disk by the time it returns and a path is what EnergyPlus is given. TypeScript's fetchWeatherFiles returns a WeatherFiles whose epw, ddy, and stat are the file TEXT, alongside a members map holding every archive member as bytes, because a browser has no disk and the text is what @idfkit/engine takes. Same name, different values, which the naming register records under the retrieved weather files: code written from one language's documentation is wrong at runtime against the other rather than merely awkward.

Three things exist on one side only, and each follows from that one fact rather than from a gap. Python's download(station, only={".epw"}) extracts a chosen subset and returns PartialWeatherFiles; selective extraction is a property of writing into a cache, and the JavaScript side decodes from memory whatever the archive held. TypeScript's FetchWeatherOptions carries fetch, rewriteUrl, and signal, because climate.onebuilding.org sends no Access-Control-Allow-Origin header and a page can reach it only through a proxy the caller supplies; Python runs under no same-origin policy and owns its own urllib requests. TypeScript splits retrieving from writing, so @idfkit/weather/node adds saveWeatherFiles and SavedWeatherFiles, where in Python the two are one operation.

Resolving a canonical EPW filename differs in one argument. Python's index parameter is optional and defaults to the bundled index, because it can always find one on disk. TypeScript's is required, because the caller had to obtain an index already and the function has nowhere to load one from.

typescript = "partial" records the missing selective extraction and nothing else. It is not a verdict on the on-disk cache: that is weather-file-cache, which is permanently absent by decision rather than missing.

Vocabulary this capability owns in the naming register
  • download a weather file
  • download a station's EPW file
  • download an EPW file by filename
  • download a station's archive
  • the retrieved weather files
  • read a ZIP archive
  • the injectable fetch
  • write weather files to disk
  • the written weather file paths

Declaring the conformance level a release passes

Python complete · JavaScript complete · Tier 1 · ledger id conformance-declaration

Vocabulary this capability owns in the naming register
  • declared conformance level

Geocoding a place name

Python complete · JavaScript complete · Tier 1 · ledger id geocoding

Vocabulary this capability owns in the naming register
  • geocode a place name
  • detect the current location
  • the geocoding rate limiter
  • a geocoding failure

Tier 2: portable, not ported yet

Capabilities the second language could have and does not have today. Every entry carries a tracking issue, because recording any of them as permanent would claim more than the code supports.

Formatting-preserving round-trip

Python complete · JavaScript complete · Tier 2 · ledger id lossless-round-trip

Vocabulary this capability owns in the naming register
  • preserve formatting on a round-trip
  • the original source text
  • label a field the author left without a comment
  • the objects a preserving write will rewrite
  • the retained source structure

Reading geometry from a model

Python complete · JavaScript partial · Tier 2 · ledger id geometry-extraction

What differs, and why

TypeScript carries the vector, the polygon and the resolved scene. getScene places every detailed surface a model states and reports what it could not place and what it did not attempt, so a reader who wants a model's geometry has it in both languages.

What it does not carry is the per-object calculation surface Python spells as free functions over an IDF object: a zone's origin and its rotation, a surface's area, tilt and azimuth read from the object rather than from a polygon, a zone's floor area, ceiling area, height and volume, and the two-dimensional polygon predicates. Python's translate_to_world has no counterpart either, and will not have the same one: it resolves by mutating the document, where getScene resolves into a value and leaves the model alone.

Vocabulary this capability owns in the naming register
  • three-dimensional vector
  • three-dimensional polygon
  • read a surface's coordinates
  • a zone's origin
  • a zone's rotation
  • transform relative coordinates to world coordinates
  • a surface's area
  • a surface's tilt
  • a surface's azimuth
  • a zone's floor area
  • a zone's volume
  • a model's resolved geometry
  • the resolved scene
  • a resolved surface
  • the rules resolution applied
  • the scene's extent
  • a surface that could not be resolved
  • a geometry type the reader did not attempt

Building and transforming geometry

Python complete · JavaScript absent (not yet) · Tier 2 · ledger id geometry-authoring

Not in JavaScript yet

A temporary gap, not a boundary. The port is tracked in idfkit-js#14.

Vocabulary this capability owns in the naming register
  • set the window to wall ratio
  • rotate a building
  • translate a building
  • scale a building
  • add a shading block
  • set default constructions

Intersecting and matching surfaces

Python complete · JavaScript absent (not yet) · Tier 2 · ledger id surface-matching

Not in JavaScript yet

A temporary gap, not a boundary. The port is tracked in idfkit-js#15.

Vocabulary this capability owns in the naming register
  • intersect and match surfaces
  • a surface match report

Generating zoned blocks from a footprint

Python complete · JavaScript absent (not yet) · Tier 2 · ledger id zoning

Not in JavaScript yet

A temporary gap, not a boundary. The port is tracked in idfkit-js#16.

Vocabulary this capability owns in the naming register
  • create a zoned block
  • a zone footprint
  • a zoning scheme
  • link blocks

Construction thermal properties

Python complete · JavaScript absent (not yet) · Tier 2 · ledger id thermal-properties

Not in JavaScript yet

A temporary gap, not a boundary. The port is tracked in idfkit-js#17.

Vocabulary this capability owns in the naming register
  • construction thermal properties
  • a construction's U-value
  • a construction's R-value
  • a construction's solar heat gain coefficient
  • a construction's layers

Schedule evaluation

Python complete · JavaScript absent (not yet) · Tier 2 · ledger id schedules

Not in JavaScript yet

A temporary gap, not a boundary. The port is tracked in idfkit-js#18.

Vocabulary this capability owns in the naming register
  • evaluate a schedule
  • a schedule's values for a year
  • a schedule as a series
  • create a constant schedule
  • create a compact schedule
  • extract special days
  • the holidays in a model

Reading the output variable dictionary and selecting variables

Python complete · JavaScript absent (not yet) · Tier 2 · ledger id output-variable-selection

Not in JavaScript yet

A temporary gap, not a boundary. The port is tracked in idfkit-js#19.

Vocabulary this capability owns in the naming register
  • read the output variable dictionary
  • an output variable
  • an output meter
  • select output variables for a run

Design days and ASHRAE sizing conditions

Python complete · JavaScript absent (not yet) · Tier 2 · ledger id design-day-sizing

Not in JavaScript yet

A temporary gap, not a boundary. The port is tracked in idfkit-js#20.

Vocabulary this capability owns in the naming register
  • apply ASHRAE sizing conditions
  • the design day manager

Reading an EPW weather file

Python complete · JavaScript complete · Tier 2 · ledger id weather-file-reading

Vocabulary this capability owns in the naming register
  • read a weather file from text
  • read a weather file from a source
  • the weather file a reader returns
  • monthly aggregates of a weather file

Tier 3: tooling and Node-bound capabilities

Absent from JavaScript today and not permanently so. Each one is reachable in Node, which is why none of them is recorded as permanent.

Forward-migrating a model between EnergyPlus versions

Python complete · JavaScript absent (not yet) · Tier 3 · ledger id version-migration

Not in JavaScript yet

A temporary gap, not a boundary. The port is tracked in idfkit-js#21.

Vocabulary this capability owns in the naming register
  • migrate a model to a newer version
  • a migration report
  • a migration step

Command-line interface

Python complete · JavaScript absent (not yet) · Tier 3 · ledger id command-line

Not in JavaScript yet

A temporary gap, not a boundary. The port is tracked in idfkit-js#22.

Vocabulary this capability owns in the naming register
  • the command line entry point

Checking source against another EnergyPlus version's schema

Python complete · JavaScript absent (not yet) · Tier 3 · ledger id schema-compatibility-check

Not in JavaScript yet

A temporary gap, not a boundary. The port is tracked in idfkit-js#23.

Vocabulary this capability owns in the naming register
  • check source compatibility with a version
  • diff two schemas
  • a compatibility diagnostic

Plotting simulation results

Python complete · JavaScript absent (not yet) · Tier 3 · ledger id result-plotting

Not in JavaScript yet

A temporary gap, not a boundary. The port is tracked in idfkit-js#24.

Vocabulary this capability owns in the naming register
  • plot an energy balance
  • plot a temperature profile
  • plot comfort hours
  • a plotting backend

Permanently single-language

Pairs of capabilities that were never one capability. Neither library is missing anything here, which is why these entries sit apart from the gaps above: each pair is two different mechanisms serving two different runtimes.

Running a locally installed EnergyPlus and reading its results

Python complete · JavaScript absent (never) · Permanently single-language · ledger id local-simulation

Python only, permanently

Requires an EnergyPlus installation on the machine and a subprocess to drive it, then reads the eplusout files that run leaves on disk. Neither the installation nor the subprocess is available in a browser, which is the runtime the JavaScript library targets. JavaScript reaches EnergyPlus by the other mechanism instead: see browser-simulation, which is not a workaround for this entry but a different capability.

Vocabulary this capability owns in the naming register
  • the local simulation surface

Running EnergyPlus in the browser

Python absent (never) · JavaScript complete · Permanently single-language · ledger id browser-simulation

JavaScript only, permanently

Delivered by @idfkit/engine, installed separately and deliberately not part of the shared install name: not a subpath, not a dependency, not an optional peer (research R19). The WebAssembly build exists to reach a runtime Python does not target, so Python has no counterpart and is not getting one. @idfkit/engine-assets is roughly 51 MB and versions on the EnergyPlus release it carries, while the loader versions on its own API, which is a second reason the facade does not carry it.

This is not a gap in Python. Python runs EnergyPlus by the other mechanism: see local-simulation.

Rendering a model to a vector image

Python complete · JavaScript absent (never) · Permanently single-language · ledger id svg-visualisation

Python only, permanently

A Python-side capability with no JavaScript counterpart and no plan for one. The output is a static vector image produced for a notebook, a report, or a file on disk, which is a Python workflow. A JavaScript caller wanting to look at a model is already in a runtime that draws, and is served by the other mechanism: see scene-rendering. Recording the two as one visualization entry would make each language read as missing something the other has, which is exactly the failure FR-078 and FR-068 forbid.

Vocabulary this capability owns in the naming register
  • the vector image surface

Rendering a three-dimensional scene

Python absent (never) · JavaScript absent (never) · Permanently single-language · ledger id scene-rendering

Permanently absent

To be delivered by @idfkit/viewer, installed by its own name like the simulation engine, and NOT reachable through the shared install name: no subpath, no dependency, no export-map entry, and no reserved name in the naming register. A reader would reach it by installing it explicitly, and the documentation says so rather than implying the facade carries it.

@idfkit/viewer DOES NOT EXIST. This row read typescript = "complete" until the change that landed geometry extraction, and no such package is in idfkit-js/packages, published or unpublished. The distinction matters more here than the word "unreachable" carries on its own: a reader meeting only this row would otherwise conclude that a renderer is a npm install away, and a specification waiting on one would be waiting on a claim rather than on a package. Nothing in feature 009 depends on this row's value, and nothing waiting on a renderer may.

The single absence_kind covers two absences of different character, and the file has one field for it. Python's absence is terminal: a real-time interactive scene needs a rendering context that a Python process does not have, and Python's static vector output is a different mechanism serving a different workflow, svg-visualisation. Neither is a gap in the other. TypeScript's absence is merely present-tense, and the never this row carries is the one its tier already states: this capability is not part of the shared surface in either language, whoever builds it and whenever.

eppy compatibility surface

Python complete · JavaScript absent (never) · Permanently single-language · ledger id eppy-compatibility

Python only, permanently

A Python ecosystem concern with no JavaScript counterpart. These methods exist solely so that code written against eppy keeps working after a move to idfkit; every one of them names an idfkit alternative in its own docstring. There is no eppy in JavaScript, so there is nothing to be compatible with. Listed explicitly so it is never ported by mistake.

Vocabulary this capability owns in the naming register
  • eppy compatibility surface

Caching retrieved weather files on disk

Python complete · JavaScript absent (never) · Permanently single-language · ledger id weather-file-cache

Python only, permanently

FR-031, stated as a decision rather than a backlog item: the on-disk cache for retrieved weather and design-day files is Python's, and JavaScript MUST NOT grow one. Moving this entry out of never needs a constitutional amendment, not an edit here.

What Python has. WeatherDownloader owns a cache directory, per platform by default and moved with cache_dir or IDFKIT_CACHE_DIR. download() looks in it first and reaches the network only on a miss or past max_age, so the second call for a station costs nothing; clear_cache empties it. Everything downstream follows: the record it returns is paths rather than text, zip_path addresses the archive it kept, and selective extraction through only= is meaningful because a suffix skipped this time may already be sitting there from an earlier call.

Why JavaScript will not have one. @idfkit/weather targets a browser, a worker, and an edge runtime as well as Node. Two of those have no directory it could own, and picking one in Node would make the package behave differently depending on where it runs, which is the one thing a portable package must not do. So it fetches every time and returns text the caller keeps. saveWeatherFiles in @idfkit/weather/node writes a retrieved bundle where the caller says, and that is a caller-directed write rather than a cache: it consults nothing on the way in and remembers nothing on the way out.

This is not a gap in JavaScript, and it is why several one-sided names exist on each side. The station index is shipped, not cached, in both languages (FR-043, FR-075), so nothing here changes how either library finds a station: that is weather-index. Retrieval itself is present in both languages: that is weather-download.

Vocabulary this capability owns in the naming register
  • the weather file cache

Language service for IDF text

Python absent (never) · JavaScript complete · Permanently single-language · ledger id idf-language-service

JavaScript only, permanently

Deliberately second-language-only. The answers are computed from byte offsets into the source text, and a second implementation of that arithmetic is the drift surface the corpus is least able to police: it compares findings on (code, line, typeName) and never on a column, so two implementations could disagree about a position for a long time without any gate noticing.

The editor extension serves both file kinds without a port. Its existing server, written in Python, continues to serve Python source; a second server written in JavaScript serves IDF text and wraps this capability. One implementation, two servers.

What this costs a reader: getting these answers requires a JavaScript runtime. pip install idfkit alone does not provide them.

Vocabulary this capability owns in the naming register
  • scan IDF text
  • classify IDF text
  • line and column at an offset
  • offset at a line and column
  • a source region
  • a line and column
  • a syntax token
  • a syntax token kind
  • the syntax layer
  • a written statement
  • schema prose pool
  • cursor context
  • completions at an offset
  • explanation at an offset
  • declaration at an offset
  • position findings
  • position findings already in hand
  • the cursor context record
  • a positioned finding
  • a completion offer
  • an explanation
  • a declaration site
  • the completion options
  • a completion result
  • an explanation result
  • a declaration result