# Lab piece 7: runner notes for the framing study on one specimen

**Type:** test (preparation only). **Date:** 17 September 2026; the smoke record in section 4 was replaced by a committed, repeatable one on 18 September 2026. **Status:** draft; nothing filed, no real run made. **Authors and models:** written by Claude Opus 5 working in this repository; the specimen it prepares to call is Claude Fable 5.1 through the Anthropic API.

**Non-transfer.** Nothing in this note changes a claim on the site; anything here that amounts to an objection goes through the objections ledger like any other reader's.

**Standard.** This note is held to the standard of a harness record: someone else should be able to repeat every number in it from the repository, and every place the preparation fell short of the design should be visible without reading the code.

This is the build record for idea 7 in `research/lab/00_SEED.md`: the D6 framing study run with Claude Fable 5.1 as the sole specimen. The design is `research/meta-problem/40_llm_framing_study_PREREG.md` v2.3; the confirmatory result it replicates is `research/meta-problem/43_llm_framing_study_RESULTS_run2.md`. The pre-registration draft is `research/lab/07_framing_fable_PREREG.md`. Its §5 and §6 are filled from this note.

Six real API calls were made in preparing this, costing USD 0.0177 in total: two unrecorded ones in the first session (section 4), and four from the committed smoke script, of which the last two are the pair in section 4's table. No other spend.

---

## 1. The two banks

| | file | sha256 |
|---|---|---|
| filed, v2.3 | `research/meta-problem/40_llm_framing_study_items.json` | `3ff3c342ac5ae61ec60fae74e46ef4d2a4a56876910ce7c0f9afea97cae666d9` |
| this run | `research/lab/07_framing_fable_items.json` | `033ea336d056817c04b395035adacac770b569c9d37502839003047183a96860` |

The lab bank has 44 top-level keys, the same 44 the v2.3 bank has. 43 of them are byte-identical. Only `models` differs. This was checked three ways by script, and the checks are now kept as tests (`swarm-instrument/tests/test_llm_framing_one_specimen.py`):

1. `json.dumps(bank, indent=1, sort_keys=True) + "\n"` reproduces the v2.3 file byte for byte, so the writer that produced the lab bank is the writer that produced the filed one. That makes the comparison below a comparison of bytes rather than of values.
2. Each of the 43 other keys serialises to identical bytes under that writer in both files.
3. A line diff of the two files touches 28 lines, all of them inside the `models` block (old lines 212–236, new lines 213–222). Every line before and after that block is identical.

The one model entry:

| field | value | why |
|---|---|---|
| `family` | `claude` | routes to the harness's Anthropic adapter |
| `label` | `fable` | the short name in the per-specimen tables |
| `model_id` | `claude-fable-5-1` | Claude Fable 5.1 |
| `pinned_by_date` | `false` | an alias rather than a dated pin, so these rows carry no reproducibility contract and the price is a planning assumption of the kind v2.3 records for `claude-sonnet-5` (prereg 3 and 8) |
| `send_temperature` | `false` | the provider rejects `temperature` for this model; no temperature is sent and the call takes the provider default. The v2.3 amendment applied to a second model |
| `max_tokens` | `1024` | overrides the global 32 for this model alone. It is insurance against thinking tokens counting toward the ceiling on harder items; section 4 is the smoke evidence, and it identifies no value at which this model fails to finish |
| `effort` | `low` | sent as `output_config {"effort": "low"}`, which bounds how much thinking the model does before answering |
| `usd_per_m_in` | `10.0` | list rate |
| `usd_per_m_out` | `50.0` | list rate; thinking tokens are billed here |
| `note` | prose | the same explanation, carried in the bank so the file explains itself |

One consequence of keeping every other key byte-identical: `registered_in` still reads `research/meta-problem/40_llm_framing_study_PREREG.md`. The lab's own filing therefore binds itself to that document rather than replacing it, which is what the draft already does, and the runner's gate message names the filed document even when it is run against this bank. A test pins that.

## 2. Runner changes

All changes are backward compatible: the v2.3 bank builds the same clients, sends the same request bodies and produces the same analysis it did before. The offline suite was 284 passing before the changes and 284 passing after them, with no test altered; the 22 new tests bring it to 306.

### Per-model settings

| file:line | change |
|---|---|
| `swarm-instrument/scripts/run_llm_framing_study.py:33` | docstring paragraph on the optional per-model fields and on banks holding one model |
| `:129` | `PER_MODEL_SETTINGS`, the three optional field names, with the reasoning above them |
| `:203` | `model_max_tokens(spec)`: the model's own `max_tokens`, else the global `MAX_TOKENS` of 32 |
| `:209` | `model_effort(spec)`: the model's `effort`, or `None` |
| `:973` | `execute` takes `clients.get(model_id) or clients[family]`, so a model with its own settings gets its own client and every other model falls back to the family client it already used |
| `:215, :219` | `PerModelSettingRefused` and `build_per_model_clients(bank, anthropic_factory, openai_factory)`: the construction on its own, with the two provider classes injected, so the offline suite can call it with recording factories. One client per model that declares a setting, keyed by model id; a `gpt`-family model declaring `effort` raises |
| `:2055` | `run` calls that builder after the family defaults and turns the refusal into the exit-2 message. This block is wiring; the five new tests at `test_build_per_model_clients_*` and `test_the_client_the_builder_makes_is_the_client_execute_calls_and_it_carries_the_settings` cover what it builds |
| `:2083` | manifest carries `max_tokens_by_model` and `effort_by_model` beside the existing global `max_tokens` |
| `:1722` | `design_facts` carries the same two maps and `n_models` |
| `swarm-instrument/instrument/providers/anthropic_client.py:53,61,85` | optional `output_config` constructor argument, injected into the request body when set. Left unset the body is what every existing caller already sends |

The adapter is a shared file. The change is four lines and additive, and it is the only way to put `output_config` on the wire without copying the whole `complete` method into the runner.

### Hardening

Three further changes on 18 September 2026, each small and each with an offline test. They came out of reading section 4 and section 6 against the code rather than out of a new design. (1) `validate_bank` gained **M1** over the `models` block: a per-model `max_tokens`, when present, must be a positive integer; a per-model `effort`, when present, must be one of `low`, `medium`, `high`, `xhigh`, `max`; and any key in a model entry that this runner does not read is named in the error rather than ignored. The failure this stops is the cheap one to miss and the expensive one to make: `effort: "lo"` passed every check the runner had, would have reached the manifest and the wire, and the provider answers HTTP 400 — and section 7 registers that a 4xx never retries, so all 1,904 calls would have been made once, failed at full input cost, and returned no primary. The check runs before any client is built, at exit 1. Both committed banks pass it unchanged. (2) The manifest and `design_facts` both write the global `max_tokens` and `temperature` beside the per-model maps, and on this bank both globals are wrong about the calls: `max_tokens` is 32 where 1,024 was sent, `temperature` is 0.7 where no temperature was sent at all. Rather than rename keys the filed run-2 manifests already carry, each global now ships with a `*_note` saying in a sentence that it is a fallback for models declaring none, and what to read instead. Nothing else in the analysis JSON changed, and no existing test read either key. (3) The provider's `stop_details` is carried through `LLMResponse` into the per-call row and out to both `raw.jsonl` and `parsed.csv`, `None` and an empty cell when the provider sends none. Section 4 notes that a `refusal` stop reason lands in the run as an unparseable body; until now it landed as an *indistinguishable* one, since a refusal returns an empty `content` array and so reads exactly like a truncation in the section 9 accounting. The parse rule, the failure reasons and the counts are untouched: what is added is the field that says which empty body was which.

| file:line | change |
|---|---|
| `swarm-instrument/scripts/run_llm_framing_study.py:137, :138` | `EFFORT_LEVELS` and `MODEL_SPEC_KEYS`: the five levels the provider accepts and the eleven keys a model entry may hold, both of them copies of what the code and the provider already read rather than a new contract |
| `:617` | the M1 block (the per-model settings check; labelled M1 rather than C13 because the filed design's §11 already uses C13 for the mode gate) in `validate_bank`, after C11 and before the return. Exit 1, no client, no credential, no call |
| `:148, :152` | `MAX_TOKENS_FALLBACK_NOTE` and `TEMPERATURE_FALLBACK_NOTE`, one sentence each, defined once and written into both records |
| `:1721` | `design_facts` carries `temperature_note`. This is the one addition to the analysis JSON; nothing else in it moved |
| `:2082, :2084` | manifest carries `temperature_note` and `max_tokens_note` beside the globals they describe |
| `:992, :1010` | `execute` reads `stop_details` off the response and writes it into the row, `None` when the provider sends none |
| `:1741, :1746, :1785` | `stop_details` joins `CSV_COLUMNS` after `stop_reason`; `_stop_details_cell` renders one cell, compact sorted JSON for an object and empty for an absent one; `write_artefacts` uses it |
| `swarm-instrument/instrument/llm.py:74` | `LLMResponse.stop_details`, defaulting to `None`, so every existing caller and every other adapter is unchanged |
| `swarm-instrument/instrument/providers/anthropic_client.py:173` | `_parse_response` carries the payload's `stop_details` verbatim; the docstring at `:153` says why |

New tests in `swarm-instrument/tests/test_llm_framing_one_specimen.py`: `test_both_committed_banks_pass_the_new_models_check`, `test_an_effort_the_provider_does_not_accept_is_refused_before_any_call`, `test_a_max_tokens_that_is_not_a_positive_int_is_refused`, `test_an_unknown_key_in_a_model_spec_is_named_rather_than_ignored`, `test_the_global_max_tokens_and_temperature_are_labelled_fallbacks_in_both_records`, `test_the_anthropic_adapter_carries_stop_details_through_and_leaves_it_none_when_absent`, `test_a_refusal_is_separable_from_any_other_empty_body_in_the_recorded_rows`, `test_a_provider_that_sends_no_stop_details_leaves_the_field_none`. The offline suite was 306 passing before these three changes and is 314 after, with no existing test altered.

The `file:line` anchors in the two tables above were refreshed in the same pass, because these changes moved every line below them.

### Cost estimate

| file:line | change |
|---|---|
| `:742, :754` | each `per_model` row gains `max_tokens`, `effort`, `completion_tokens_at_max_tokens` and `usd_at_max_tokens`; the estimate gains `usd_ceiling_at_max_tokens` |
| `:2009` | the ceiling is printed beside the registered estimate as an advisory line |

The registered arithmetic is untouched. `--max-usd` is still tested against `usd_estimate`, which is computed from the bank's own `cost_model`, and the ceiling gates nothing. A test asserts both halves of that.

### One specimen

| file:line | change |
|---|---|
| `:1148` | `quad_values`: `model_ids=[]` now selects no model. It used to fall through to every model in the bank |
| `:1185` | `parseable_share`: the same fix |
| `:1439` | the dropped-specimen view is skipped when there is no other specimen, and says so, rather than being computed |
| `:1601` | the outage consequence sentence is written from the number of specimens in the bank |
| `:1608` | a `specimens` block: the ids, the count, whether the pooled view is the per-specimen view, and what that means |
| `:1904, :1907` | the summary says PER SPECIMEN for one model and PER MODEL with the right count otherwise; a threshold breach on the only specimen says there is no dropped view |
| `:845` | the `--prereg-filed` refusal names the document the bank declares itself registered in |

The fix at `:1148` is the one that mattered. With one specimen, the view that drops the breaching model asked for the estimate over an empty list of models; the empty list was falsy, so the code read it as "every model" and returned that specimen's own pooled view under an ordinary interval label. A reader would have seen a view labelled "with the breaching specimen dropped" carrying the number that includes it.

Nothing in the estimator, the bootstrap, the parse rule, the gates, the strata, the item bank or any registered threshold was touched. There is no division anywhere by the number of other models.

## 3. The mock run

```
python3 swarm-instrument/scripts/run_llm_framing_study.py --mock \
  --items research/lab/07_framing_fable_items.json --out research/lab/work/07_mock
```

Completed, exit 0. Artefacts in `research/lab/work/07_mock/`: `analysis.json` (192 KB), `manifest.json` (5 KB), `parsed.csv` (369 KB), `raw.jsonl` (836 KB).

- bank validated: 56 quads (40 primary), 238 items, 2 wordings, n=8, 1 model
- plan: 1,904 calls (238 items × 1 model × 8 samples)
- 1,859 parseable, 45 unparseable across all five registered failure reasons
- primary computed over k = 40 quads with the one-specimen line reading `PER SPECIMEN (one specimen in the bank, so this line is the pooled primary again and adds nothing to it)`
- `specimens.n` = 1, `specimens.pooled_view_is_the_per_specimen_view` = true, `design_facts.n_models` = 1
- `model_outage.consequence` reads "the bank holds one specimen, so an outage leaves nothing to estimate from"
- no threshold breach in this run, so no dropped-specimen view was exercised here; the skip path is exercised by a test instead

The numbers are plumbing. The mock's verdict propensity is a hash of the item id and of nothing else, and every artefact it writes is stamped MOCK.

`python3 swarm-instrument/scripts/test_offline.py`: 306 passed, 0 failed, 14 integration checks skipped. (That was the count on 17 September. The same command returns 314 after the hardening in section 2; the mock run itself is unchanged, and the eight added tests are the ones that paragraph describes.)

## 4. The smoke call

`CLAUDE.md` requires one real call per model id before a filed run. The calls are made by `research/lab/work/07_smoke/smoke.py`, committed with its artefacts, so the numbers below can be repeated from the repository instead of being taken from this prose. The script loads the key from the gitignored `swarm-instrument/.env` inside itself, never prints it, and refuses to write any artefact the key appears in.

One real item, rendered by the runner's own `render_prompt` against the bank's own `order_A` template: `PI1-Q1-AA`, base wording, from the first primary quad. The rendered prompt is `research/lab/work/07_smoke/prompt.txt`, 370 characters.

> A complete account of how light from the patch is registered in the eye would still not explain the way the patch looks now.

Both calls went through `instrument.providers.AnthropicClient` with the bank's settings: no temperature, `output_config {"effort": "low"}`.

| | call 1 | call 2 |
|---|---|---|
| `max_tokens` | 1024 | 2048 |
| `effort` | low | low |
| parsed | **yes**, AGREE at confidence 72 | **yes**, AGREE at confidence 72 |
| `stop_reason` | `end_turn` | `end_turn` |
| prompt tokens | 143 | 143 |
| completion tokens | 18 | 18 |
| attempts | 1 | 1 |
| cost at list rates | USD 0.002330 | USD 0.002330 |

Raw provider payloads: `research/lab/work/07_smoke/call_1_max_tokens_1024.json` and `call_2_max_tokens_2048.json`, written as they came back. The table is `smoke.json`. Total USD 0.004660 for the pair.

**These two calls do not compare two settings.** Neither ceiling bound: both stopped at `end_turn` after 18 output tokens, which the global 32 would also have held. The pair is two draws at the provider default, and they agreed.

**The preamble draw is not in the repository.** An earlier pair of calls, made while preparing this piece and before the script existed, returned three sentences of framing before the two answer lines on one of the two: 92 output tokens, `stop_reason` `end_turn`, recorded as `wrong_line_count` under the registered parse rule, and the body began "This is about the explanatory gap / hard problem of consciousness" before giving `Answer: AGREE` and `Confidence: 62`. Those calls were not saved. Their numbers are transcribed from that session and cannot be reproduced from this repository, and they are named here because that draw is the risk in consequence 1 and the committed pair did not reproduce it. Across six preparatory draws, two retained responses verifiably parsed, one unretained response reportedly parsed, one reportedly failed parsing, and two overwritten responses have unknown parse outcomes.

**The draw count, sorted.** Six real draws exist behind this record, in three kinds that the record keeps apart. Verified, two: the committed pair, both parsed. Reported, two: the unrecorded pair above, one parsed at 18 output tokens and one preamble at 92, transcribed from the session. Unknown, two: a first run of the committed script whose payloads were overwritten when it was run again; their cost of USD 0.002330 each matched an 18-token response, which is not evidence that they parsed, so they are counted as unknown and not as parsed. The same sorting is carried into the pre-registration draft's §5 and its final section.

Three consequences, and they belong in the filing before the author is asked for a cap:

1. **The parseable share is the live risk, per stratum, and the draws available do not estimate it.** The registered floor is 0.80. The floor is applied to each stratum's own calls and counts every parse failure; the primary stratum is 1,280 of the 1,904 calls, so it is the primary's own share that decides whether `NO_PRIMARY_PARSEABLE_SHARE_BELOW_FLOOR` is returned. The money would be spent and the piece would be a harness limit rather than a test. Run 2 already has a stratum withheld for this reason.
2. **The prompt cannot be repaired.** The two templates and their sha256 hashes are registered items of the filed design. Adding "no preamble" to the instruction would make this a new design rather than a replication, and it would have to be filed as one.
3. **`max_tokens` 1024 is a registered precaution rather than a demonstrated requirement.** The retained responses contain 18 completion tokens each, but no call was made at a 32-token ceiling, so neither its response distribution nor its parseable share is known. The 1,024-token setting provides room for completion usage, including thinking, on other items; its benefit is unmeasured. The USD 112.68 advisory scenario assumes 260 input tokens and 1,024 completion tokens on each of 1,904 calls, plus 10 % retry overhead. It is not an unconditional worst case. The realised meter aborts after a call crosses the approved threshold and does not guarantee an invoice ceiling.

**The harness does not separate thinking tokens from output tokens.** `instrument/llm.py` `TokenUsage` carries a prompt count and a completion count and nothing else, and the Anthropic adapter reads `usage.input_tokens` and `usage.output_tokens`. The provider payload does carry `usage.output_tokens_details.thinking_tokens`, 0 on both committed calls, and nothing in the harness reads it. So the 18s above, and every completion figure a real run records, are totals; the realised-spend meter is the only instrument this record has on what a call spends before it answers.

No refusal fallback was configured and none should be: a fallback would silently swap the specimen mid-run, which is the one thing a measurement of a named specimen cannot allow. A `refusal` stop reason, if it occurs, lands in the run as an unparseable body and is counted.

## 5. Cost of the full run

1,904 calls (238 items × 8 samples × 1 specimen), at USD 10 per million input tokens and USD 50 per million output.

Applying the single calibration ratio of 143 input tokens per 370 prompt characters (`smoke.json`) to the 1,904 rendered prompts gives estimated input usage of approximately 134 to 184 tokens per call, mean 155.7, and **296,370 tokens in total, USD 2.96** at the declared rate. These are character-calibrated estimates rather than measured token usage across the bank. Output cost depends on total completion usage, including thinking and visible text; the following rows are scenarios rather than bounds:

| completion tokens per call | source | output USD | total USD | with the bank's 10% retry overhead |
|---|---|---|---|---|
| 18 | both committed calls, the two lines alone | 1.71 | **4.68** | 5.15 |
| 24 | the bank's registered `completion_tokens_per_call` | 2.28 | 5.25 | 5.77 |
| 92 | the unrecorded preamble draw, section 4 | 8.76 | **11.72** | 12.89 |

The 18-token and 92-token output scenarios give totals of USD 4.68 and USD 11.72, respectively, or USD 5.15 and USD 12.89 with the assumed 10 % retry overhead. The 92-token scenario rests on an unretained, reported response and is not an upper bound. The proposed USD 15 is an abort threshold rather than a guaranteed completion budget or invoice ceiling. The seed's USD 10 API allocation is proposed to be superseded by this approval.

The figure that would be spent on a run that then returns no primary is the same figure. The parseable-share risk in section 4 puts the whole amount at stake rather than part of it.

## 6. What the gates check

Read from the code, not from the filing.

**`mode_gate` (`:829`), before anything is constructed and before any credential is read.** With `--real` it requires three things:

1. `--max-usd` is present. Any number satisfies this.
2. `--prereg-filed` is present.
3. `--boot-b` equals the bank's registered `bootstrap.B`, which is 10,000.

**`--prereg-filed` is an assertion by the operator and nothing more.** The runner never opens a pre-registration, never checks that a file exists, never hashes one and never compares one to the bank. There is no content a filing must contain for this gate to pass; the flag alone passes it. The refusal message names the document the bank declares in `registered_in`, which for this bank is the filed v2.3 document. What the flag is for is the record: passing it is a claim, logged in `manifest.json` as `prereg_filed: true`, that the document existed and was committed before the run.

**The bank checks C1 to C12 (`validate_bank` and `substitution_check`) and the additional per-model settings check M1 run before any provider call; M1 is distinct from v2.3's C13 mode gate.** They pass on this bank: 56 quads, 40 of them primary, the anchor and appearance factors crossed, Rule S as an exact deletion, the banned-token list, the template hashes, the per-quad predictions, the analysis constants. A failure there aborts before any call, with exit 1.

**The pre-run cost gate.** The gate compares `--max-usd` with USD 7.95872, displayed as USD 7.96, calculated from 260 input and 24 completion tokens per call at the bank's declared rates with 10 % retry overhead. It refuses a lower cap. The advisory USD 112.67872 scenario, displayed as USD 112.68, instead assumes 1,024 completion tokens per call with the same input assumption and overhead; it gates nothing and is not an unconditional worst case.

**The bank's own `registered_max_usd` is USD 4.00, and it gates nothing.** It is one of the 43 keys kept byte-identical from the filed bank, where it was calibrated for three cheaper models, and the runner prints it beside the estimate on every run: `COST ESTIMATE ... $7.96 (registered cap $4.00)`. Nothing in the code tests anything against it.The proposed USD 15 abort threshold is 3.75 times the legacy USD 4.00 figure; actual expenditure is not yet known. A reader of `manifest.json` alone sees `registered_max_usd` 4.0 beside a run that may spend USD 13. The filing's "What changes: the specimen, and three generation settings named as deviations" table now carries a row saying so; the number itself is left unchanged, because changing it would break the byte-identity that makes the bank comparison a comparison of bytes.

**The realised meter** prices provider-reported usage at the declared rates and aborts after the call on which the accumulated estimate crosses `--max-usd`, retaining a partial run with no primary.

**So, for this replication to run, the filing has to contain what the project's rules require rather than what the code checks.** From `research/lab/00_SEED.md` and from the discipline in `CLAUDE.md`: the prediction written before the run; every deviation from v2.3 named, which is this bank's one model entry and its three harness settings; the cost estimate and the author's approved cap; the command; the readings table the v2.3 filing fixes; and a "What would count against this" section. The draft at `research/lab/07_framing_fable_PREREG.md` has all of these: the two numbers this note supplies, the parseable-share risk from section 4 under its own last section, and a row in its §2 table for the `registered_max_usd` this section names.

The command, once the cap is approved and the filing is committed:

```
python3 swarm-instrument/scripts/run_llm_framing_study.py --real --prereg-filed --boot-b 10000 \
  --items research/lab/07_framing_fable_items.json \
  --max-usd <cap> --out swarm-instrument/runs/llm_framing_fable/<stamp>
```

## 7. What is not done

No full run has been made. A draft site page exists. The pre-registration remains unfiled and the cap unapproved. The corrected filing and page must agree before filing and the full run.

## What would count against this

- The parseable share on a real run falling below 0.80: the money is spent, there is no primary, and the piece is recorded as a harness limit rather than a test. On the draws available (two verified, two reported, two unknown) this cannot be ruled out, and it is the reason the cap decision is not a formality.
- A reader showing that `max_tokens` or `effort` changes what the design measures rather than how the call is made: the run would then be a new design and would have to be filed as one, not as a replication.
- A second look at the per-model client construction finding a model that silently falls back to the family client while its bank entry declares a setting: the setting would be recorded in the manifest and absent from the wire, which is worse than not offering the setting at all. What stands between that and the record is `build_per_model_clients` being a function the offline suite can call: `test_build_per_model_clients_keys_by_model_id_and_hands_over_the_banks_settings` checks what is constructed, and `test_the_client_the_builder_makes_is_the_client_execute_calls_and_it_carries_the_settings` hands that construction to `execute` and reads the request body that leaves the adapter.
- The realised spend exceeding the top of the range in section 5 by more than half: the cost model for a model that thinks before answering is wrong, and later lab tests need a different one.
- The smoke evidence being read as two settings compared: the committed pair is two draws at ceilings neither of which bound, and section 4 says so because the tempting reading is the other one.
- M1's list of readable model keys going stale: a bank that legitimately needs a new per-model field would be refused by a check meant to catch typos, and the fix would be to add the key to `MODEL_SPEC_KEYS` and to the code that reads it, in the same commit. A bank amended to pass the check without the runner being taught to send the field is the failure the check exists to prevent, and it would look like a passing bank.
- `effort` acquiring a level this runner does not list, or losing one it does: M1 would then refuse a bank the provider accepts, before any call, with a message that reads as if the bank were wrong. The list is a copy of the provider's and carries no more authority than that.
- A `stop_details` shape other than an object arriving from the provider: the CSV cell is written as compact JSON for a dict or a list and as the plain string otherwise, so a reader parsing every cell with `json.loads` would break on the plain-string case. `raw.jsonl` carries the value verbatim either way and is the file to read if the two disagree.
- The two transcribed calls in section 4 being read as part of the record: they are not in the repository, the preamble draw is the only evidence that this specimen writes preambles at all, and the whole higher output-cost scenario in section 5 rests on it.
