docs(deferment): #552 (session-stated topByTimestamp) + #553 (evidence-preserving CSV merge) closed; residuals #554/#555 filed

This commit is contained in:
Joseph Doherty
2026-08-10 01:24:59 -04:00
parent 1f351250ed
commit 36c82b60f7
+49
View File
@@ -1280,6 +1280,55 @@ drivers), 3 carried-open archreview findings led by 01/S-1 (`AddressSpaceApplier
---
### 2026-08-10 (later) — #552 + #553 closed: the browse states, the merge preserves
The two residuals the #550/#551 round exposed, again two isolated-worktree Opus agents, merged
`1f351250` (#552) + `62fe6c83` (#553). Consolidated verification on the merged tree: full build
clean; 8 suites / 3,362 tests green (AdminUI 1262, ControlPlane 261, Sql 363, Sql.Browser 79,
MTConnect 534, Modbus 373, S7 285, TwinCAT 205).
- **#552 CLOSED** — Sql browse-commit emits a valid `rowSelector`. The **session states, the mapper
never infers** (the MQTT Sparkplug rule): `SqlBrowseSession` names a `topByTimestamp` candidate
from the column `DATA_TYPE` metadata it already reads (`MapColumnType == DateTime` — type only,
never a name heuristic; the fixture pins a `sample_ts TEXT` trap column), tie-break = first in
catalog order (every dialect's `ListColumnsSql` already orders by ordinal), zero extra queries
(pinned by a command-count test). New `SqlBrowseAddressFields` constants in `Driver.Sql.Contracts`
end the producer/consumer agree-by-coincidence on field names. No-candidate tables are refused
**in words at the modal** (`DescribeUncommittableLeaf` — names leaf, table, and the
whereColumn/whereValue fix, whose value is *data* no browse can supply); the emitted blob keeps
the wide-row shape so table/column survive into the typed editor. The blob's top-level
`timestampColumn` (source-timestamp) is deliberately NOT set — ordering by a column is not a
claim it timestamps the value. Emitted blobs are double-accepted (model validator AND the real
`SqlEquipmentTagParser`) with a pre-#552-bytes-refused control; the `RawTagConfigGateTests` Sql
leg flipped from records-the-gap to passes-the-gate.
- **#553 CLOSED — and characterization first shrank it.** On the current tree (post-#550/#551)
MTConnect's invalid-alias/invalid-cell legs were ALREADY caught (raw-key maps never round-trip);
the real defects were the model-backed maps' laundering (Modbus/S7 `"dataType":"Intt16"` →
silent `Int16`) and the **export side actively setting the re-import trap** (`ReadTypedColumns`
read only the canonical key → the typed column printed the *ignored* value, the residual kept the
*winning* alias). Fix is evidence preservation, not a second validator:
`ApplyTypedColumns` restores the base cell's own tokens over the model serialisation for every
key no non-blank column overrode (fragments compose byte-identically; the #551 gate stays the one
authority, now judging unlaundered evidence); `CsvTypedColumn.ReadKeys`/`OwnedJsonKeys` declare
the runtime's full spelling precedence once (MTConnect pairs), so firing columns clear
out-ranking aliases, the export residual strips them, and export cells show the effective value.
Override-contradiction semantics: column wins, OPENLY (review grid names each override) — #549's
doctrine is against *silent* rewrites. Falsification: guard neutered → exactly the 7
defect-closers red while the #551 gate suites stayed 53/53 green (a layer in front of the gate,
not a replacement).
- **The deliberate-trap discipline in the #552 fixtures is worth copying:** the multi-candidate
table's column names are asserted to DISAGREE with alphabetical order (the tie-break test cannot
pass by luck), and the no-candidate table carries the exact `sample_ts TEXT` column a name
heuristic would have bound to.
- **Residuals filed, not folded in:** **#554** — authoring models validate only enum keys; non-enum
rules (Modbus address shapes, S7 stringLength bounds…) meet no gate until deploy, where the #551
accept-gate-first Inspect names them — feedback latency, not silent death; closing it means the
models consult the same runtime parse the Inspects wrap, after a fleet survey (N-1 rule).
**#555** — `RawBrowseCommitMapper`'s fallback comment cites a `RawBrowseCommitMapperParityTests`
guard that DOES NOT EXIST; the "every browsable driver handled" invariant is unguarded (9 types
covered by hand-written InlineData) — write the `DriverTypeNames.All`-driven parity test the
comment already describes.
### 2026-08-10 — #550 + #551 closed: the accept-gate-first fleet conversion
The two #549-survey residuals, again two isolated-worktree Opus agents, merged `b50523b1` (#550) +