Opaque identifier grouping a run of adjacent content lines.
docs/prose-dialect-spec.md §3.7/§8d.2 (RULED): “block id is universal”
— every run of same-element adjacent content lines carries one; hosts
aggregate consecutive OutputLines sharing a BlockId or ignore it
entirely. Two OutputLines carry the same id iff they belong to the same
uninterrupted run — a terminal (Step::Choices/Step::Done/
Step::End) or a host-directed jump always starts a new one.
Compile-time-baked block ids (per §3.6’s attachment mechanism) are a
superset of this. Issue #2108 (docs/decision-log.md 2026-08-03 “The
element output model”) delivers the first real instance: an
attach = StructName convention handler’s data is merged into the VM’s
output buffer (brink_runtime::vm’s Opcode::AttachElement/
Opcode::EndElementRun) and every line materialized while it’s live gets
a copy in Element::data — but BlockId itself is not re-derived
from that mechanism; it stays the plain terminator-counting value it
always was (this field’s own next_block_id doc, brink_runtime::story:: call_stack::Flow). A run of adjacent lines sharing one attach group can
therefore span more than one BlockId if it also crosses a real
terminator — the two concepts have not been unified.