Sandpies Claude Opus 5 commited on
Commit
4f98438
·
1 Parent(s): 1b0e265

plan: a place the film never left is not a new place

Browse files

check_place_handoff's arrival half compared each beat against shot N-1 only,
so a location established in shot 1 and not re-named in shot 2 read as newly
arrived in shot 3. Live: platform / (unnamed) / platform on a chain that
spends every hop on one platform, warning that shot 2 "never goes there" when
shot 2 is standing on it.

The film's current place carries forward across beats that name none. What the
check is actually about is whether this beat names somewhere other than where
the previous hop ENDED, because that is what the live frame at its first frame
shows. Leaving and coming back -- kitchen / hallway / kitchen -- is still a
move and still warns.

Third lint this session with the same defect: tested against the wrong
baseline, and every one of them was telling the author to change work that was
already right.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014VB4Dw6F79643vySkf19KV

Files changed (2) hide show
  1. plan.py +23 -15
  2. tools/check_templates.py +32 -0
plan.py CHANGED
@@ -246,21 +246,29 @@ def check_place_handoff(shots, ref_plan=None):
246
  "makes her way", "makes his way", "makes their way",
247
  )
248
 
249
- for i in range(1, len(shots)):
250
- prev = (shots[i - 1].get("beat") or "").lower()
251
- here = shots[i].get("beat") or ""
252
- low = here.lower()
253
- new_places = [t for t in places
254
- if ("@" + t).lower() in low and ("@" + t).lower() not in prev]
255
- for tag in sorted(new_places):
256
- if any(v in low for v in _ARRIVES):
257
- continue
258
- warnings.append(
259
- f"shot {i + 1}: @{tag} is a new place and shot {i} never goes there. "
260
- f"The hop opens on a live frame of the old location, so the only way "
261
- f"to obey is a cut. End shot {i} with the arrival, or have shot "
262
- f"{i + 1} do the travelling."
263
- )
 
 
 
 
 
 
 
 
264
 
265
  # The same defect seen from the other side. Both LM Studio models plated
266
  # the opening location, moved the story somewhere else, and gave the new
 
246
  "makes her way", "makes his way", "makes their way",
247
  )
248
 
249
+ # Where the film currently IS, carried forward across beats that name no
250
+ # place at all. Comparing only against shot N-1 made a place the film never
251
+ # left read as newly arrived the moment one beat in the middle did not
252
+ # happen to name it: platform / (unnamed) / platform warned on shot 3, for
253
+ # a chain that spends every hop on one platform. What matters is whether
254
+ # this beat names somewhere OTHER than where the previous hop ended, which
255
+ # is what the live frame at its first frame actually shows.
256
+ current = set()
257
+ for i, s in enumerate(shots):
258
+ low = (s.get("beat") or "").lower()
259
+ named = {t for t in places if ("@" + t).lower() in low}
260
+ if i and current:
261
+ for tag in sorted(named - current):
262
+ if any(v in low for v in _ARRIVES):
263
+ continue
264
+ warnings.append(
265
+ f"shot {i + 1}: @{tag} is a new place and shot {i} is "
266
+ f"somewhere else. The hop opens on a live frame of the old "
267
+ f"location, so the only way to obey is a cut. End shot {i} "
268
+ f"with the arrival, or have shot {i + 1} do the travelling."
269
+ )
270
+ if named:
271
+ current = named
272
 
273
  # The same defect seen from the other side. Both LM Studio models plated
274
  # the opening location, moved the story somewhere else, and gave the new
tools/check_templates.py CHANGED
@@ -141,6 +141,38 @@ def main():
141
  print(" FAIL %s: warned=%s wanted=%s" % (label, got, want))
142
  fails.append(label)
143
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  # The last shot of any pattern that ends a chain must not be left `ongoing`.
145
  closers = [s for s in all_shots
146
  if (s["directives"].get("tail") in ("settle", "hold"))]
 
141
  print(" FAIL %s: warned=%s wanted=%s" % (label, got, want))
142
  fails.append(label)
143
 
144
+ # ...and the arrival half has to carry the current place forward across a
145
+ # beat that names none. Comparing only against shot N-1 made a place the
146
+ # film never left read as newly arrived: platform / (unnamed) / platform
147
+ # warned on shot 3, live, for a chain that spends every hop on one
148
+ # platform.
149
+ def _b(*beats):
150
+ return [{"beat": b} for b in beats]
151
+
152
+ for label, sh, plan, want in (
153
+ ("one place, a beat that does not name it",
154
+ _b("walks along the @platform", "moves past the yellow lines",
155
+ "slows her pace on the @platform"),
156
+ _pl({"tag": "platform"}, {"tag": "her", "subject": 1}), False),
157
+ ("leaving and coming back is still a move",
158
+ _b("in the @kitchen", "down the @hallway", "back in the @kitchen"),
159
+ _pl({"tag": "kitchen"}, {"tag": "hallway"},
160
+ {"tag": "her", "subject": 1}), True),
161
+ ("a new place with no arrival still warns",
162
+ _b("in the @kitchen", "across the @lamp_room floor"),
163
+ _pl({"tag": "kitchen"}, {"tag": "lamp_room"},
164
+ {"tag": "her", "subject": 1}), True),
165
+ ("a beat that does the travelling does not",
166
+ _b("in the @kitchen", "she reaches the @lamp_room and stops"),
167
+ _pl({"tag": "kitchen"}, {"tag": "lamp_room"},
168
+ {"tag": "her", "subject": 1}), False)):
169
+ got = any("is a new place" in w for w in PL.check_place_handoff(sh, plan))
170
+ if got == want:
171
+ print(" ok %s" % label)
172
+ else:
173
+ print(" FAIL %s: warned=%s wanted=%s" % (label, got, want))
174
+ fails.append(label)
175
+
176
  # The last shot of any pattern that ends a chain must not be left `ongoing`.
177
  closers = [s for s in all_shots
178
  if (s["directives"].get("tail") in ("settle", "hold"))]