{
  "api_version": "v1",
  "dataset_version": "AdityaNet_v2_dataset_r1",
  "dataset_sha256": "43fd0e228b28ae6bc7e468c3acf68722768bd62b73798eb6631e9e6233b71ed9",
  "generated_at": "2026-07-29T13:34:16.814931+00:00",
  "source_commit": "99af630",
  "data": {
    "id": "CONTRADICTION-004",
    "slug": "contradiction-004",
    "title": "two HEL1OS parser-level rules are falsified",
    "state": "CLOSED",
    "date": "2026-07-17",
    "reason": "Two \u00a72.x parser-level rules falsified by real HEL1OS data. RESOLVED by spec r4.",
    "resolving_revision": "r4",
    "status_line": "Status: CLOSED 2026-07-17 \u2014 the owner ruled the defects independent and adjudicated them separately. Applied as PARSER_SPECIFICATION.md r4 (\u00a710). Milestone V now passes 124/124. See COMPLIANCE_M5.md.",
    "declined_amendment": true,
    "lead": "**Status: CLOSED 2026-07-17 \u2014 the owner ruled the defects independent and adjudicated them separately. Applied as PARSER_SPECIFICATION.md r4 (\u00a710). Milestone V now passes 124/124. See COMPLIANCE_M5.md.**\n\n**Defect A: APPROVED in full.** R-1 gains H3 (relative seconds), evaluated H3\u2192H1\u2192H2, terminating only if all fail; H1/H2 retained for future compatibility; composition rule recorded; **A-11** added.\n\n**Defect B: PARTIALLY APPROVED \u2014 the owner's ruling is narrower than my proposal, and better.** The validation contract changes; **the parser behaviour does not**. My proposal to stable-sort inside the parser was **DECLINED**. Instead the parser preserves archive order exactly and remains a **lossless representation of the archive**; chronological ordering is an explicit, documented, out-of-parser utility. **A-12** added; no jitter threshold defined.\n\n*Why the owner was right:* the ruling establishes a **general v2 principle** \u2014 reading and transforming are separate acts. My version would have made the parser silently reorder. The owner's keeps it a faithful reader and forces every consumer to opt in visibly. That is the difference between a parser and a pipeline.\n\nRaised under: *\"Do not pause implementation unless another parser-level contradiction is proven.\"* Two are proven. Unlike CONTRADICTION-003 (scientific interpretation, deferred), **both defects below are parser-correctness issues**: the parsers terminate on real data and cannot proceed.\n\n**Milestone V status: 3 of 5 HEL1OS parsers pass on real data** \u2014 light curves (5 bands, 43,171 rows), GTI (1 interval, 43,178.29 s), events (5,796,441 events across all 4 detector HDUs). **Spectra and housekeeping are blocked.**\n\n---",
    "sections": [
      {
        "heading": "DEFECT A \u2014 \u00a72.7's rule R-1 enumerates the wrong hypotheses",
        "body": "### The rule\n> **Resolution rule R-1:** at implementation, test the column against both hypotheses (Unix-s and MJD-days) and accept the one reproducing the header `TSTART/TSTOP` span to <1 s; if neither fits \u2192 **F-06, terminate**.\n\nThe parser did exactly this and terminated. Residuals: **5,271,868,808 s** (MJD-days hypothesis), **1,765,152,008 s** (Unix-seconds hypothesis). Neither is remotely close.\n\n### What the column actually is (`OBSERVED`, `hel1os_czt_spectra_czt1.fits`)\n\n| Quantity | Value |\n|---|---|\n| col `TSTART` | `[0.0, 20.0, 40.0, \u2026, 43120.0]`, n=2157 |\n| col `TSTOP[0]` | `20.0` |\n| `EXPOSURE` | **uniform 20.0 s** |\n| header `TSTART` / `TSTOP` | `61017.0000988685` / `61017.49963590554` **MJD** |\n| header span | **43,160.0 s** |\n| column span | **43,120.0 s** (= span \u2212 one 20 s bin at each end) |\n\n**`TSTART` is seconds elapsed since the orbit start**, i.e. relative to the header `TSTART`. The first value is exactly `0.0`; the step is exactly `EXPOSURE`; the span matches the header to within one bin.\n\n### Why the contract got it wrong\n\n\u00a72.7 framed the ambiguity as *\"column declares unit='s' but header TSTART is MJD\"* and concluded the **epoch** was undetermined. That framing was wrong. **The `unit='s'` declaration was correct all along** \u2014 the column really is seconds. The genuine unknown was never the *unit*, it was the **origin**. Both metadata statements are true and **compose**: absolute time = `mjd_to_utc(header TSTART) + column TSTART seconds`. R-1 offered two absolute-epoch hypotheses and omitted the relative one, which is the true one.\n\nThis is a **third instance of the same root cause** as CONTRADICTION-001 and -003: I asserted a relationship between two fields from their declared metadata without computing it. R-1 was written to guard exactly this class of error and still fell to it \u2014 because a hypothesis test can only find hypotheses you enumerate.\n\n### Proposed amendment (NOT applied)\n1. **\u00a72.7 R-1** \u2014 add **H3 (relative seconds)** and test it **first**, since `unit='s'` literally declares seconds: accept H3 iff `col[0] == 0` (exactly) **and** `|col_span \u2212 header_span|` \u2264 one `EXPOSURE` bin. Retain H1/H2 as fallbacks; terminate via F-06 only if **all three** fail.\n2. **\u00a72.7** \u2014 record the composition rule: *absolute time = `mjd_to_utc(header TSTART) + column TSTART`*; the column is an offset, never an epoch.\n3. **\u00a78** \u2014 new assumption **A-11**: the relative-seconds convention is VERIFIED on one orbit only. Milestone VIII must verify across all 391 HEL1OS orbits; deviation terminates validation.\n\n---"
      },
      {
        "heading": "DEFECT B \u2014 \u00a72.8's \"mjd non-decreasing\" is falsified",
        "body": "### The rule\n> **Validation:** `mjd` non-decreasing; `czt1temp`/`czt2temp` finite; `suninfov \u2208 {0,1}`.\n\n### The data (`OBSERVED`, `aux/hk.fits`, orbit `HLS_20251208_000008`)\n\n| Quantity | Value |\n|---|---|\n| Rows | 9,514 |\n| **Decreasing steps** | **424** (4.5 % of 9,513 steps) |\n| Zero steps (duplicates) | **0** |\n| All values unique | **True** |\n| First decrease (row 925) | `61017.024131` \u2192 `61017.024131`, **\u0394 = \u22120.0133 s** |\n| **Max backward step** *(corrected 2026-07-17)* | **\u22120.8924 s** (median \u22120.718 s) |\n| Global range | `61017.000099` \u2192 `61017.499848` \u2014 correct, and within the header span |\n\n**CORRECTION (post-approval):** this document originally characterised the backward steps as \"~13 milliseconds\". That was the **first** inversion, not the maximum. Measured properly: **max 892.4 ms, median 718.0 ms**. The steps are sub-second but an order of magnitude larger than stated. **The owner's ruling is unaffected** \u2014 statistics are recorded and never thresholded, so no approved decision rested on the wrong figure \u2014 but the error is recorded here rather than quietly fixed, because a contradiction report that misstates its own evidence is exactly the failure mode this process exists to catch. Every timestamp is unique, the global span is right, and the ordering is otherwise correct. This is **sub-second telemetry packet-arrival jitter**, not corruption: housekeeping packets are written in arrival order, which is not exactly time order.\n\n`INFERRED`: `mjd` is a *measurement*, not an *index*. The contract assumed it was sorted; the archive stores it as recorded.\n\n### Why this matters\n`suninfov`, the pile-up counters, the saturation counters and the HV monitors all live in this table \u2014 it is Phase 1a's only source of instrument state. Terminating on 13 ms of jitter would make HEL1OS housekeeping **unparseable archive-wide**.\n\n### Proposed amendment (NOT applied)\n1. **\u00a72.8 validation** \u2014 replace *\"`mjd` non-decreasing\"* with: *`mjd` MUST be finite and **unique**; the global span MUST lie within the header `TSTART`/`TSTOP`. Raw arrival order is **not** required to be sorted.*\n2. **\u00a72.8 parser behaviour** \u2014 the HK table is returned **stably sorted by `mjd`**, and the provenance MUST record `n_out_of_order` and `max_backward_step_s`. **This is a reordering, not a repair**: no value is created, altered, imputed or dropped, and the transformation is recorded rather than silent. *(Flagged explicitly for the owner: this is the first transformation any v2 parser performs. The alternative \u2014 return unsorted and push the problem to M-VII \u2014 is defensible; I do not think it is better, because an unsorted time series is a footgun for every downstream consumer, but the choice is the owner's.)*\n3. **No threshold is proposed.** The magnitude of the jitter is **reported**, never compared against an invented tolerance. Encoding \"13 ms is acceptable\" would repeat the error the owner correctly rejected in CONTRADICTION-003.\n4. **\u00a78** \u2014 new assumption **A-12**: HK time jitter is characterised on one orbit only; Milestone VIII must report the distribution of `max_backward_step_s` across all 391 orbits. A **drifting or growing** jitter is a scientific finding.\n\n---"
      },
      {
        "heading": "State of the work",
        "body": "Milestone V is **paused with the code committed and both parsers terminating exactly as the frozen contract requires**. Nothing has been weakened: R-1 still enumerates only two hypotheses; \u00a72.8 still demands non-decreasing `mjd`. The three passing parsers (LC, GTI, events) are unaffected and their tests are not yet written \u2014 Milestone V's test suite and compliance report follow once these two rules are resolved.\n\n**RESOLVED.** Both defects closed by r4.\n\n**Post-approval correction (recorded, not quietly fixed):** this document originally cited the HK backward steps as \"~13 ms\" \u2014 that was the *first* inversion, not the maximum. Measured properly: **max 892.4 ms, median 718.0 ms**, an order of magnitude larger. **No approved decision rested on the wrong figure** (statistics are recorded, never thresholded), but a contradiction report that misstates its own evidence is precisely the failure mode this process exists to catch, so the error is logged rather than edited away.\n\n**One implementation detail resolved within the approved rule (not a contract change):** \"col_span\" in H3 is computed as the **data span** (`tstop[-1] \u2212 tstart[0]` = 43,140 s), not start-to-start (43,120 s), which would silently omit the final bin's duration and understate the span by exactly one EXPOSURE. With the data span the residual is exactly one 20 s bin, as the rule requires. A documented IEEE754 slack (1 ms \u2014 ~3 orders above the float64 MJD ULP of ~6e-7 s, ~4 orders below the 20 s bin) absorbs MJD\u2192seconds conversion noise, because the comparison lands exactly *on* the boundary. **This is numerical slack, not physical tolerance.**\n\n**Carried to Milestone VIII:** A-11 (verify the relative-seconds convention across all 391 orbits) and A-12 (report the `max_backward_step_s` distribution across all 391 orbits; drifting or growing jitter is a scientific finding)."
      }
    ],
    "source": "artifacts/v2/phase05/CONTRADICTION-004.md"
  }
}
