1. The ruling had no normative/API surface. §1.1 assigns authority, but Pin 3
still said "nothing else in core" and the touch table listed graph.rs under
"Not touched" -- leaving the contract and P13-S16 as the only carriers of
supposedly normative meaning while core_spec.tex remained ambiguous. A
normative ruling that lives only in a contract is not normative.
Added pin 4b requiring all four sites, and narrowed pin 3 to the codec
surface ("no other CODE change in core"):
- graph.rs:819 Staff.group -- sole authority. Note this field has NO doc
comment today; it must be written, not amended.
- graph.rs:1614 StaffGroup.members -- non-authoritative projection, must
not be read for membership, may be stale in both directions. Also
currently undocumented.
- core_spec.tex at the Staff/StaffGroup declarations -- the same rule
normatively. This is the document that declared both fields without
ranking them, so it is where the ambiguity actually lives.
- operation_catalog.tex -- explicit stale-form semantics in the new
CreateStaffGroup section AND the existing CreateStaff section (:1104).
CreateStaff needs it because it is the operation that creates the
missing form, and its section currently promises nothing.
Each cross-references P13-S16. graph.rs moves into the touch table
(documentation only; no type changes anywhere in core). Added t14 to guard
the two field doc comments, sliced per-field on t12's discipline since a
file-wide grep cannot fail here.
2. t8b's two mutations were assigned to the reducer that runs FIRST in each
order, so neither could reach the state its assertion names:
- Missing form (CreateStaffGroup then CreateStaff): create_staff_group
cannot append a staff that does not exist yet. Mutation moved to
create_staff -- append the newly minted staff to g.members.
- Spurious form (CreateStaff then CreateStaffGroup): create_staff has no
later group to repair. Mutation moved to create_staff_group -- reject or
normalize away the non-empty carried members.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QjsEnYhm1gPpf6ii2iFxFV