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

1 participant