oonirun: specify configuration model, target identity and attribution - #310
Open
hellais wants to merge 5 commits into
Open
oonirun: specify configuration model, target identity and attribution#310hellais wants to merge 5 commits into
hellais wants to merge 5 commits into
Conversation
Three additions and a set of corrections to the OONI Run v2 spec, motivated by the plan to rebuild the instant-messaging cards as links composed from web_connectivity building blocks, and by the data pipeline's requirements on provenance and series stability. Configuration model (3.1). Reinstates the nettest-level `options` object alongside the per-input `inputs_extra` overlay, with defined merge semantics: engine defaults, then options, then inputs_extra[i], shallow merge. Without a nettest-level object, input-less nettests had no configuration surface at all and shared settings had to be duplicated into every inputs_extra entry. Backends validate option names at CREATE so a typo fails loudly instead of silently doing nothing in the field; probes ignore unknown names so old probes keep working. The safe_ prefix convention, which the spec used but never documented, is now stated together with its scrubbing rule. The effective per-input configuration is recorded in the measurement, so analysis can condition on what actually ran. Target identity (3.2). Inputs are addresses and may rotate freely between revisions; targets are durable names, expressed as service roles and never as addresses, kept in a shared append-only registry. Inputs sharing a target_id form a redundant pool; the breaks_service flag marks a target whose blocking breaks the whole service for the user, the way WhatsApp registration does regardless of the chat pool. One declaration drives the probe-side card status and the pipeline-side aggregation, which is what lets an IM card decompose into web_connectivity runs without collapsing into per-hostname series that break at every infrastructure rename. Measurement attribution (5.0). Probes annotate every measurement with the link id, the revision and a per-run attempt id, which is what scopes aggregates to a campaign and reconstructs a composed link as one logical check. Consent is defined to bind to revisions rather than resolutions: a volunteer consents to the named list, not to the specific inputs it yields on a given day, so dynamic-list churn no longer re-prompts while every definition change still does. Resolutions themselves are ephemeral by design, since retaining every prioritization output would grow without bound; the measurements submitted under one attempt are the durable record of what was served, and the spec states the accepted tradeoff that the unmeasured remainder is not reconstructible. Corrections: duplicate 4.4 heading renumbered (engine descriptor is now 4.5, LIST is 4.6, and it is titled POST, which is what it specifies); stale v1 API path and run.ooni.io addresses updated; expired/archived terminology unified; User-Agent field list typo fixed.
hellais
commented
Aug 5, 2026
Additions and corrections to the OONI Run v2 spec, motivated by the plan to rebuild the instant-messaging cards as links composed from web_connectivity building blocks, and by the data pipeline's requirements on provenance and series stability. Configuration model (3.1). Reinstates the nettest-level `options` object alongside the per-input `inputs_extra` overlay, with defined merge semantics: engine defaults, then options, then inputs_extra[i], shallow merge. Without a nettest-level object, input-less nettests had no configuration surface at all and shared settings had to be duplicated into every inputs_extra entry. Backends validate option names at CREATE so a typo fails loudly instead of silently doing nothing in the field; probes ignore unknown names so old probes keep working. The safe_ prefix convention, which the spec used but never documented, is now stated together with its scrubbing rule. The effective per-input configuration is recorded in the measurement, so analysis can condition on what actually ran. Target identity (3.2). Inputs are addresses and may rotate freely between revisions; targets are durable names, expressed as service roles and never as addresses, kept in a shared append-only registry. Inputs sharing a target_id form a redundant pool; the breaks_service flag marks a target whose blocking breaks the whole service for the user. The state of a composed link is evaluated in two explicit steps: a target is down only when every pool member fails, and the service is broken when any breaks_service target is down. One declaration drives the probe-side card status and the pipeline-side aggregation, which is what lets an IM card decompose into web_connectivity runs without collapsing into per-hostname series that break at every infrastructure rename. Dynamic target lists (3.3). targets_name names a backend-generated input list and shares its namespace with the target registry: the stock Websites card uses citizenlab/test_lists, while a registry target_id (ex. whatsapp/endpoints) expands to the target's current members with the identity keys stamped on the served entries. A composed IM link is therefore written entirely without addresses, and pool rotation happens in the registry as a new resolution, with no link revision and no renewed consent. Names are owned and validated by the backend; probes treat them as opaque and never validate against a hardcoded list, so new names ship without a client update. Measurement attribution (5.0). Probes annotate every measurement with the link id, the revision and a per-run attempt id, which is what scopes aggregates to a campaign and reconstructs a composed link as one logical check. Consent is defined to bind to revisions rather than resolutions: a volunteer consents to the named list, not to the specific inputs it yields on a given day, so dynamic-list churn no longer re-prompts while every definition change still does. Resolutions themselves are ephemeral by design, since retaining every prioritization output would grow without bound; the measurements submitted under one attempt are the durable record of what was served, and the spec states the accepted tradeoff that the unmeasured remainder is not reconstructible. Corrections: duplicate 4.4 heading renumbered (engine descriptor is now 4.5, LIST is 4.6, and it is titled POST, which is what it specifies); stale v1 API path and run.ooni.io addresses updated; expired/archived terminology unified; User-Agent field list typo fixed.
* 'oonirun-v2.2' of github.com:ooni/spec: oonirun: specify configuration model, target identity and attribution
hellais
marked this pull request as ready for review
August 6, 2026 11:13
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.
Three additions and a set of corrections to the OONI Run v2 spec, motivated by the changes to support oonirun v2.1 in miniooni, the plan to rebuild the instant-messaging cards as links composed from web_connectivity building blocks, and by the data pipeline's requirements on provenance and series stability.
It also folds into the spec some implicit changes introduce in ooni/probe-cli#1812 and reserves some special keys in
inputs_extraon which specific semantics are attached.In theory nothing in this spec should require additional engine or backend changes, except for
ooni_run_link_revision(should be easy) andooni_run_attempt(might be harder).Below is a more comprehensive description of the changes
Configuration model (3.1). Reinstates the nettest-level
optionsobject alongside the per-inputinputs_extraoverlay, with defined merge semantics: engine defaults, then options, then inputs_extra[i], shallow merge. Without a nettest-level object, input-less nettests had no configuration surface at all and shared settings had to be duplicated into every inputs_extra entry. Backends validate option names at CREATE so a typo fails loudly instead of silently doing nothing in the field; probes ignore unknown names so old probes keep working. The safe_ prefix convention, which the spec used but never documented, is now stated together with its scrubbing rule. The effective per-input configuration is recorded in the measurement, so analysis can condition on what actually ran.Target identity (3.2). Inputs are addresses and may rotate freely between revisions; targets are durable names, expressed as service roles and never as addresses, kept in a shared append-only registry. Inputs sharing a target_id form a redundant pool; the breaks_service flag marks a target whose blocking breaks the whole service for the user, the way WhatsApp registration does regardless of the chat pool. One declaration drives the probe-side card status and the pipeline-side aggregation, which is what lets an IM card decompose into web_connectivity runs without collapsing into per-hostname series that break at every infrastructure rename.
Measurement attribution (5.0). Probes annotate every measurement with the link id, the revision and a per-run attempt id, which is what scopes aggregates to a campaign and reconstructs a composed link as one logical check. Consent is defined to bind to revisions rather than resolutions: a volunteer consents to the named list, not to the specific inputs it yields on a given day, so dynamic-list churn no longer re-prompts while every definition change still does. Resolutions themselves are ephemeral by design, since retaining every prioritization output would grow without bound; the measurements submitted under one attempt are the durable record of what was served, and the spec states the accepted tradeoff that the unmeasured remainder is not reconstructible.
Corrections: duplicate 4.4 heading renumbered (engine descriptor is now 4.5, LIST is 4.6, and it is titled POST, which is what it specifies); stale v1 API path and run.ooni.io addresses updated; expired/archived terminology unified; User-Agent field list typo fixed.
PR companion to OONI Runv2.1 changes in miniooni: ooni/probe-cli#1812