Version: v0.1
Date: 2026-08-21
Status: STANDING. Binding on change requests that add a value to a function already carrying a # FORAY_RESERVED_LOCATION marker. Markdown primary — the consumer is Claude Code and future change-request drafting.
Occasion: CR-2026-233 (R-2, Gate 1) §11 and §7c — a forward gap opened between two correct pieces of work and was found by pre-flighting, not by reading. Filed because the rule that closed it was earned in a commit message and needs to live where a CR draft will find it.
Reads with: foray-reference/loomworks-foray-r2-forward-gap-scoping-note-v0_4; change-requests/cr-2026-233-foray-r2-forward-gap-closure-v0_2 §3a, §7c, §8, §11; standing-notes/loomworks-standing-note-migrations-and-the-code-that-runs-at-another-time-v0_2.
A # FORAY_RESERVED_LOCATION marker is a promise about a function: everything the function knows that is worth attesting will reach the emit payload. That promise is checked once, when the marker is placed. Nothing checks it again.
So a later change that adds a new value to the same function — a new parameter, a new field on a row already in scope — can silently break the promise. The value is real, it is in scope, and it does not reach the payload, because the change that added it was not looking at the marker two lines away.
This happened once in this arc, inside eleven days, between two pieces of work that were each individually correct. The rule below is what would have caught it without needing anyone to notice.
The rule: a change request that puts a value in scope at a site carrying a # FORAY_RESERVED_LOCATION marker forwards it to the emit payload in the same change.
> A change request that puts a value in scope at a site carrying a # FORAY_RESERVED_LOCATION marker forwards it to the emit payload in the same change.
Why this and not a periodic audit. An audit finds the gap eventually, at a cost that grows with how long it sat open — and every FORAY-adjacent CR since the gap opened has to be re-checked once the audit lands. Forwarding at the point of addition costs nothing beyond what the change already touches: the value is already being named, already being typed, already being passed one function deeper. Naming it a second time, in the payload dict two lines away, is not a second design decision.
What triggers it. Not "I am writing a forward-gap CR." Any change that adds a field, a parameter, or a column to a function whose body already contains a # FORAY_RESERVED_LOCATION marker. The trigger is proximity to the marker, not the intent of the change touching it.
Site 10 — the gap that opened. credit/room_consumption.py::_emit has carried a # FORAY_RESERVED_LOCATION: credit.<event_kind> marker since Phase 64. CR-2026-231 Gate 1 added agent_actor_id and session_id to flow.extra_metadata at that exact function — new facts, newly in scope, two lines from the marker — and did not forward them to the payload.
Neither piece of work was wrong when written. CR-2026-231 §4 was scoped to the credit record and said so in its own text; it was building attribution into the spend record, not auditing FORAY coverage. The R-2 mapping that would have named this a gap was written before those two fields existed — it could not have found what was not yet there. The gap opened in the space between two correct, well-scoped pieces of work, and stayed open for eleven days until CR-2026-233's pre-flight found it by running git log against the seven FORAY-adjacent files since the mapping's last confirmed-current point — not by reading either change request, both of which read as complete on their own terms.
Site 17 — the same rule, followed before it existed. agents/lifecycle_record.py::record_lifecycle_event was written five commits later, in CR-2026-231 §7, and added a new # FORAY_RESERVED_LOCATION: agents.grant_lifecycle marker rather than touching an existing one. Its author forwarded every field the function's own INSERT writes — agent_identity_id, event_kind, session_id, reason, actor_id, actor_kind, occurred_at, engagement_id — into the payload in the same change that introduced them. CR-2026-233's independent screening at pre-flight confirmed the payload complete; no gap, no work, no CR growth.
The two instances are the same rule from opposite sides. Site 17 shows what following it looks like: the marker and the values that feed it are decided together, so there is nothing to leave out. Site 10 shows what not following it costs: the marker sat still while the function around it grew, and the two drifted apart without either author doing anything a reviewer would have flagged.
Without this rule, R-2's closure list is not a list — it is a moving target. Every change request that touches one of the seven FORAY-adjacent files after a gap-closure CR lands can reopen exactly the gap that CR just closed, the same way CR-2026-231 reopened site 10 five commits before CR-2026-233 would have closed it without the four values it added. A forward-gap CR that chases a target that moves whenever anyone touches those files never actually closes — it produces a sequence of CRs, each correct against the mapping it was drafted from, each stale by the time the next one runs.
The seven files, named so the rule has a concrete surface to watch: credit/flows.py, credit/room_consumption.py, credit/proposal_applier.py, memory/events.py, orchestration/conversation_turns.py, orchestration/tune_setting.py, api/routers/me_settings.py — plus, as of CR-2026-231 §7, agents/lifecycle_record.py. Any change to any of these that adds a value already in scope near a marker is where this rule applies.
It does not create a new review step, a new CI check, or a new template section. It states the obligation in one sentence so a CR author working near one of the marked files can recognise it without deriving it — the way §7c's rule was derived once, by a pre-flight that happened to run git log against the right files, and would otherwise have had to be re-derived by the next person who noticed the same shape.
It does not retroactively audit the other FORAY-adjacent sites for the same drift. That is what R-2's own closure passes are for, and each one now carries this rule as part of what it checks.
DUNIN7 — Done In Seven LLC — Miami, Florida Loomworks — Standing Note: A Value in Scope at a Marker Site Travels in the Same Change — v0.1 — 2026-08-21