Skip to content

Commit ad50f1b

Browse files
committed
docs: fold the fourth-reading findings into ADR 0018 and the roadmap
All six valve-actuator inspection reports and all four clean-water checklist pages read at full render. Confirmed R8, R9, R10 and R15 with exact evidence; sharpened R3 and R5; raised R20-R22. Folded into the ADR: - Section 4: a note is never an answer. The source answers several lines with a bare "see notes" and NO mark -- a cross-reference standing in place of an answer, one of which points at notes that never mention the line. R3 had modelled only the safer variant (mark AND pointer). A line with a note and no result is a blank and the gate treats it as one. - Section 8: scope widened to final control elements, not only transmitters. Every valve report records fail position on loss of signal, function, and control/feedback signal types. Fail position is the clearest case for the whole collection. Fields added; collection name unchanged. - Section 9: required signature roles come from the GC's template, never from the vendor's paper. Two failure modes in the source, not one -- a contractor block left blank on one vendor's form, and NO such block at all on another. A QC deriving who owes a signature from the attached document reports nothing missing for the worse case. New, not folded: - R20: a signed checklist's signature block sits on its own page carrying no identification of what was signed. Detached, it attests to nothing. A rationale finding for ADR 0010's signed_content_hash and a print-discipline bar for the free turnover view; recorded in ROADMAP M6.2. Also recorded: the gate form handles its one conditional item by writing the condition into the prompt text rather than branching the form -- an experienced vendor, with no tooling constraint at all, independently choosing constraint #5's answer. Cite it when conditional checklists are next proposed. Secondary input to open question 12: actuator serial number reads N/A on all six valve reports. Any asset-vs-position model must handle a position whose occupant has no serial identity at all.
1 parent d0fa2a4 commit ad50f1b

3 files changed

Lines changed: 230 additions & 14 deletions

File tree

‎docs/ROADMAP.md‎

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,12 @@ gate moves to where ambiguity becomes permanent (ADR 0018 §4).
465465
lines are unresolved, and the check lands `incomplete` as today. `sign.html`
466466
and the turnover build surface unresolved lines as the specific blocker,
467467
linking to the correction check that would clear them.
468+
- **A note is never an answer.** Result and note are separate fields; prose in
469+
the response position is not a response. A line with a note and no result is a
470+
**blank** and the gate treats it as one. The source answers several lines with
471+
a bare "see notes" and no mark — a cross-reference standing in place of an
472+
answer, one of which points at notes that never mention the line. The capture
473+
UI structurally cannot produce this shape, which is the point.
468474
- **Validation.** `na_reason` is **required when `result = "na"`**,
469475
server-enforced on `check_items`. A check may **not be signed**, and a scope
470476
may **not be frozen**, while any included line carries a blank result — the
@@ -612,19 +618,30 @@ mid-startup with nothing prompting re-verification.
612618
**Goal.** Capture what the vendor PDFs took with them when they left, and make
613619
the package refuse to be compiled with the signature block empty.
614620

615-
### M6.1 — Instrument configuration records (observation 6)
621+
### M6.1 — Instrument and final-control-element configuration records (observation 6)
616622

617623
The 4–20 mA span, the transmitter range, the delay, the logging interval, the
618624
setpoints — configured at startup, captured inside a vendor's report, and
619625
unrecoverable by the time the instrument is replaced.
620626

627+
**Scope widened after the full render of the valve reports**
628+
([review notes R21](adr/0018-review-notes.md#r21--configuration-data-lives-on-final-control-elements-not-only-instruments--folded-into-adr-0018-8)):
629+
this covers **final control elements too**, not just transmitters. Every valve
630+
report in the source records fail position on loss of input signal, function
631+
(on/off vs modulating), and control/feedback signal types. **Fail position is
632+
the clearest case for the whole collection** — configured once, recorded only in
633+
a vendor PDF, the first thing needed at replacement, and wrong answers have
634+
process consequences rather than paperwork ones.
635+
621636
- **Data model.** New **append-only `instrument_settings`**: `project`, `tag`
622637
(required), `configured_at`, `configured_by`, `vendor_company` (nullable),
623638
`input_type`, `range_low` / `range_high` / `range_unit` (the engineering
624639
range: 0–500 gpm), `signal_low` / `signal_high` / `signal_unit` (the
625640
electrical span: 4–20 mA), `damping_seconds`, `delay_seconds`,
626641
`logging_interval`, `setpoints` (text), `firmware_version`, `notes`,
627-
`superseded_by` (self-relation, nullable), `client_token`.
642+
`superseded_by` (self-relation, nullable), `client_token`; and for final
643+
control elements `fail_position`, `control_function`, `control_signal`,
644+
`feedback_signal`.
628645
`updateRule: null`, `deleteRule: null`. **Not** folded into `calibrations`:
629646
"what is it set to" and "does it read true" are different facts on different
630647
cadences (ADR 0016 rejected the analogous flattening).
@@ -665,6 +682,21 @@ missing countersignatures before the package was compiled.
665682
minus roles signed against the current `content_hash`. No stored `signed`
666683
flag (already rejected by ADR 0010). The app records who signed in what
667684
capacity; it never adjudicates who was entitled to.
685+
- **Required roles come from the GC's template, never from the vendor's paper**
686+
([review notes R22](adr/0018-review-notes.md#r22--missing-countersignature-has-two-failure-modes-and-one-has-no-block-to-leave-blank--folded-into-adr-0018-9)).
687+
The source has two failure modes: a contractor block **left blank** on one
688+
vendor's form, and on another **no such block at all** — it ends at "inspected
689+
by". A QC deriving who owes a signature from the attached document would report
690+
nothing missing for the second and worse case. The list is computed against the
691+
frozen `required_signature_roles`, independent of any attached document.
692+
- **Print discipline** ([R20](adr/0018-review-notes.md#r20--a-signature-can-sit-on-a-page-that-identifies-nothing--open)).
693+
In the source, a signed checklist's signature block sits on **its own page**,
694+
carrying a name, a wet signature, a date — and nothing identifying what was
695+
signed. Detached from the preceding sheet it attests to nothing. Every page of
696+
a printed turnover artifact must therefore carry enough identity (package id,
697+
scope, content-hash prefix) that a separated page stays traceable. This is the
698+
concrete field justification for ADR 0010's `signed_content_hash`, and it sets
699+
a bar the free print view must not regress against.
668700
- **Turnover.** A **missing-countersignature QC block** computed before the
669701
freeze is allowed.
670702

‎docs/adr/0018-multi-vendor-startup-evidence-model.md‎

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,16 @@ No project, company, vendor, or person is identified anywhere in this record.
1414
**Provenance — read this before trusting the Context section.** This ADR was
1515
written from a **summary** of those observations. The source package was read
1616
directly afterwards, on 2026-08-04, and the reading is recorded in
17-
[`0018-review-notes.md`](0018-review-notes.md). Every observation was confirmed;
18-
comments **R2, R6, R7, R8 are folded in below**, **R1 reversed a recommendation**
19-
in this ADR's open questions, and **R3–R5 remain open** for the maintainer. The
20-
Context section below is left as originally written rather than retrofitted —
21-
what the ADR knew when, and from what, is itself part of the record.
17+
[`0018-review-notes.md`](0018-review-notes.md). Every observation was confirmed.
18+
Four readings have now happened — a summary, a text-layer pass, a corrected
19+
render pass, and a full render of the valve reports and clean-water checklists.
20+
Comments **R2, R6, R7, R8, R21 and R22 are folded in below**; **R9–R12 were
21+
decided** and appear as §§13–14 and §5; **R1 proposed reversing a recommendation
22+
and was decided against**; **R3–R5 and R13–R20 remain open** for the maintainer.
23+
The Context section below is left as originally written rather than retrofitted —
24+
what the ADR knew when, and from what, is itself part of the record. Three of
25+
its ten bullets are now known to be imprecise in detail while correct in
26+
substance; the review notes carry the corrections.
2227

2328
## Context
2429

@@ -150,6 +155,16 @@ is to separate the two moments:
150155
- **`check_items.na_reason`** (text) is **required when `result = "na"`**,
151156
server-enforced by the `check_items` createRule. "N/A" with no reason is the
152157
second most ambiguous mark on a paper form.
158+
- **A note is never an answer**
159+
([R3](0018-review-notes.md#r3--pass-with-exception-is-a-real-answer-the-state-vocabulary-has-no-home-for--open)).
160+
A line carries a `result`, and separately may carry a `note`; prose in the
161+
response position is not a response. The source answers several lines with a
162+
bare **"see notes" and no mark at all** — a cross-reference standing *in place
163+
of* an answer, which reads as resolved and is not. Worse, one such pointer
164+
**dangles**: the notes it refers to say nothing about that line. So a line with
165+
a note and no `result` is a **blank**, and the gate below treats it as one. The
166+
capture UI cannot produce this shape (result control and note field are
167+
separate), which is the point — the failure is native to paper.
153168
- **`incomplete` survives, and keeps its meaning** at the check level: a run
154169
that was started and abandoned. Capture is never blocked — hard constraint #1
155170
means a laborer on a dead-zone phone must always be able to submit what they
@@ -334,13 +349,23 @@ which a naive numeric parse would read as a single value — a concrete case for
334349
the §7 rule that an unparseable reading derives nothing and the tech's explicit
335350
result stands.)
336351

337-
### 8. Instrument configuration is its own append-only ledger
352+
### 8. Configuration is its own append-only ledger — instruments **and final control elements**
338353

339354
Configured settings are neither a calibration nor a checklist. A calibration
340355
(ADR 0016) asks "does it read true?" — configuration asks "what is it set to?"
341356
They change on different schedules and for different reasons; folding settings
342357
into `calibration_points` would misrepresent both.
343358

359+
**Scope covers final control elements, not only transmitters**
360+
([R21](0018-review-notes.md#r21--configuration-data-lives-on-final-control-elements-not-only-instruments--folded-into-adr-0018-8)).
361+
Every valve report in the source captures the same class of fact on an
362+
actuator — fail position on loss of input signal, function, control-signal type,
363+
feedback-signal type. **Fail position is the single clearest case for this whole
364+
collection**: configured once, recorded only in a vendor PDF, first thing anyone
365+
needs when the actuator is replaced, and getting it wrong has process
366+
consequences rather than paperwork ones. The collection keeps the name
367+
`instrument_settings` — a tag is a tag and the record shape does not differ.
368+
344369
New append-only collection **`instrument_settings`**:
345370

346371
`project` · `tag` (required) · `configured_at` · `configured_by` ·
@@ -350,7 +375,10 @@ New append-only collection **`instrument_settings`**:
350375
`signal_low` / `signal_high` / `signal_unit` (the electrical span: 4–20 mA) ·
351376
`damping_seconds` · `delay_seconds` · `logging_interval` ·
352377
`setpoints` (text: the human list) · `firmware_version` · `notes` ·
353-
`superseded_by` (self-relation, nullable) · `client_token` (idempotent retry).
378+
`superseded_by` (self-relation, nullable) · `client_token` (idempotent retry) ·
379+
and for final control elements: `fail_position` (e.g. `close` / `open` /
380+
`last`) · `control_function` (`on_off` / `modulating`) ·
381+
`control_signal` · `feedback_signal`.
354382

355383
`updateRule: null`, `deleteRule: null`. A reconfiguration is a **new record**
356384
that the prior may point at via `superseded_by`; the **current settings are
@@ -376,6 +404,15 @@ answered.
376404
the check** at execution (`checks.required_signature_roles`), exactly like
377405
`witness_required` already does (ADR 0002). A template edited later must not
378406
change what a signed check required.
407+
- **Required roles come from the GC's template, never from the vendor's paper**
408+
([R22](0018-review-notes.md#r22--missing-countersignature-has-two-failure-modes-and-one-has-no-block-to-leave-blank--folded-into-adr-0018-9)).
409+
The source shows two failure modes, not one: a contractor block **left blank**
410+
on one vendor's form, and on another vendor's form **no such block at all** —
411+
it ends at "inspected by" and never contemplated a countersignature. A QC that
412+
derived "who still owes a signature" from what the attached document contains
413+
would report nothing missing for the second case, which is the worse one. The
414+
missing-countersignature list is therefore computed against the frozen
415+
`required_signature_roles` **independently of any attached vendor document**.
379416
- `signatures.signer_role` gains `vendor_tech`, `subcontractor`,
380417
`gc_witness`, and `controls_integrator` alongside the existing vocabulary.
381418
- **Witnessing becomes a role, not a text field.** `checks.witnessed_by` stays

0 commit comments

Comments
 (0)