DEV Community

Aleksander Sekowski
Aleksander Sekowski

Posted on Fully Autonomous

RMT mappings need an unknown state when OpenRTB fields are missing.

A mapping service can emit valid JSON and still classify an impression using evidence it never received. This often happens when an absent boolean becomes false, or a broad device label is treated as proof of a particular viewing experience.

The result looks complete in a dashboard. The uncertainty has simply been hidden upstream.

IAB's finalized September 2026 video-classification framework describes viewing environments and impression-level attributes. If you derive those attributes from OpenRTB inputs, your adapter also needs a policy for missing, unsupported and conflicting evidence.

The examples below illustrate that policy. They are application patterns, not an official RMT classifier or a normative translation of OpenRTB enums.

Preserve the observations before assigning a label

Start with the raw input and its scope. An advertised player capability, a request field and an observed playback event answer different questions. A value describing what may happen does not necessarily establish what happened during one impression.

For each input, retain its field path, producer, specification snapshot and interpretation rule. If the rule depends on an exchange-specific extension, name that contract as well.

This becomes useful when two systems disagree. You can compare the inputs and rules that produced the labels rather than arguing over the labels alone.

Avoid an early conversion such as Boolean(video.someField). It can collapse absent data, unknown enum values and malformed types into apparently meaningful results. Once that information is discarded, downstream consumers cannot recover it.

Give unknown outcomes a reason

The following complete Node.js example combines already interpreted observations. Its conservative policy requires every supplied observation to be known and consistent:

import assert from 'node:assert/strict';

function deriveAttribute(observations) {
  if (observations.length === 0) {
    return { state: 'unknown', reason: 'no-observations' };
  }
  if (observations.some(o => typeof o.value !== 'boolean')) {
    return { state: 'unknown', reason: 'incomplete-or-unsupported' };
  }
  const first = observations[0].value;
  if (observations.some(o => o.value !== first)) {
    return { state: 'unknown', reason: 'conflicting-observations' };
  }
  return { state: 'known', value: first };
}

assert.deepEqual(deriveAttribute([]),
  { state: 'unknown', reason: 'no-observations' });
assert.equal(deriveAttribute([{ value: undefined }]).state, 'unknown');
assert.equal(deriveAttribute([{ value: 'false' }]).state, 'unknown');
assert.equal(deriveAttribute([{ value: true }, { value: false }]).reason,
  'conflicting-observations');
assert.equal(deriveAttribute([{ value: true }, { value: undefined }]).state,
  'unknown');
assert.deepEqual(deriveAttribute([{ value: false }]),
  { state: 'known', value: false });
assert.deepEqual(deriveAttribute([{ value: true }, { value: true }]),
  { state: 'known', value: true });
Enter fullscreen mode Exit fullscreen mode

The explicit state prevents a known false result from being confused with an unknown result. The reason makes missing evidence distinguishable from an actual conflict.

This is one possible policy. A different integration might establish precedence among trusted sources. If you do that, make the precedence part of a versioned rule and retain the losing observation. Silently choosing the last nonempty field makes the result depend on processing order.

Separate parsing from interpretation

The parser should establish whether an OpenRTB field has the expected JSON type and a recognized value under the pinned specification. The interpretation layer should decide what that value supports for the attribute you are deriving.

Keep those results separate. A recognized enum can still be insufficient evidence for the question you want to answer. Conversely, an unsupported value should not automatically become the default member of your business taxonomy.

For example, playbackmethod is an array describing methods that may be in use. Follow the selected OpenRTB snapshot's guidance when interpreting it. Treating field presence as a direct observation of a single playback session skips the question of what the producer actually declared.

Apply the same care to measurement. Declared measurement capability and evidence that a measurement session occurred are different observations. Decide which your classification claims to represent.

Store the mapping version with the result

A useful classification record includes the input artifact reference, raw relevant values, adapter version, framework version and decision reason. Keep it small enough to attach to a sampled impression without copying unnecessary personal data into every log.

When you change a rule, replay a fixed corpus and compare outputs under both versions. Count how many labels changed and inspect examples from each changed category.

Do not overwrite yesterday's derived results without retaining which rule produced them. A reporting change might reflect a better mapping, a new producer field or a different framework definition. The versioned record lets you explain which one occurred.

If a downstream system requires a binary field, define its handling of unknown explicitly. It may omit the claim, reject the record or route it through a separate policy. The conversion should remain visible at that boundary.

Test evidence quality as well as label accuracy

Build fixtures for no input, an explicit false observation, a recognized true observation, a malformed type, an unknown enum and a conflict between sources. Each fixture should assert the reason as well as the resulting state.

Add cases where a producer changes a field from absent to explicit false. The final boolean may appear unchanged in a badly designed system, but the evidence quality has changed substantially.

Also test the scope of observations. A publisher-level capability should not accidentally be treated as a per-impression runtime fact. Use separate fixture fields or evidence types so that the distinction survives refactoring.

These tests are more useful than a fixture containing only a finished category label. They exercise the assumptions that connect the source data to the claim.

Report coverage alongside classified inventory

Suppose a synthetic batch contains 600 known true results, 300 known false results and 100 unknown results. The known true share is 600 out of 900 among classified records, while the share across all records is 600 out of 1,000. Those answer different questions.

Show the denominator and unknown count whenever presenting the result. Track unknown reasons by producer and adapter version so a sudden coverage change can be investigated.

I maintain RTBlint. Its OpenRTB video-object reference helps review the source fields. Keep the mapping rules, uncertainty policy and fixture corpus in your integration so that every derived claim can be traced back to evidence.

Sources

Technical sources checked October 25, 2026. Drafted with AI; examples are synthetic unless explicitly stated otherwise.

Top comments (0)