Skip to content

oonirun: specify configuration model, target identity and attribution - #310

Open
hellais wants to merge 5 commits into
masterfrom
oonirun-v2.2
Open

oonirun: specify configuration model, target identity and attribution#310
hellais wants to merge 5 commits into
masterfrom
oonirun-v2.2

Conversation

@hellais

@hellais hellais commented Aug 5, 2026

Copy link
Copy Markdown
Member

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_extra on 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) and ooni_run_attempt (might be harder).

Below is a more comprehensive description of the changes

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.

PR companion to OONI Runv2.1 changes in miniooni: ooni/probe-cli#1812

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.
Comment thread backends/bk-005-ooni-run-v2.md
hellais added 4 commits August 6, 2026 10:45
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
hellais marked this pull request as ready for review August 6, 2026 11:13
@hellais
hellais requested review from DecFox and aanorbel August 6, 2026 11:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant