writer: mp is not the model's field with an empty rail either
Browse files_restore_rail_only returned early when `pinned` was empty and skipped any ref
the rail did not know, so a brief-only write left the model's invented `mp`
in the register. gemma4-26b returned -1, then 1e+15. `parse_ref_plan` RAISES
on both, and validate returns that single error immediately -- so all three
attempts died on one line about megapixels, the invented filenames were never
reported, and Accept wrote a register of missing files onto the rail.
The strip is unconditional now: drop the field first, then set it from the
rail if the rail has one. A ref the rail knows nothing about is exactly the
case where the model's number is the only one there, and it is still not the
model's field to set.
Live, the brief that failed three times: ok in two attempts, mp fields empty.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014VB4Dw6F79643vySkf19KV
- planner.py +27 -19
- tools/check_planner.py +16 -0
|
@@ -722,14 +722,14 @@ def _merge_register(base_text, patch_text, keep=None):
|
|
| 722 |
return json.dumps({"refs": refs, "subjects": subs}, indent=2)
|
| 723 |
|
| 724 |
|
| 725 |
-
# Fields the RAIL owns and the
|
| 726 |
-
# person sets per row; it is absent from
|
| 727 |
-
#
|
| 728 |
-
# writes
|
| 729 |
-
# silently reset every cap to "full": chain_00047 ran three plates at
|
| 730 |
-
# (1.58 MP total against a 0.72 MP canvas) and the next write put the
|
| 731 |
-
# three back at native size, 3.23 MP, which is the run that came back with
|
| 732 |
-
# reference photograph rendered instead of the beat.
|
| 733 |
RAIL_ONLY_FIELDS = ("mp",)
|
| 734 |
|
| 735 |
|
|
@@ -740,14 +740,20 @@ def _restore_rail_only(ref_text, pinned):
|
|
| 740 |
REMOVED, it is not left as the model wrote it. `mp` is exposed in the
|
| 741 |
schema so a hand-authored plan can set one, which means a model can put a
|
| 742 |
number there too -- gemma4-26b read the units as pixels and returned
|
| 743 |
-
1000000000
|
| 744 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 745 |
"""
|
| 746 |
obj = _parse_obj(ref_text)
|
| 747 |
-
if not isinstance(obj, dict)
|
| 748 |
return ref_text
|
| 749 |
by_tag, by_file = {}, {}
|
| 750 |
-
for p in pinned:
|
| 751 |
if not isinstance(p, dict):
|
| 752 |
continue
|
| 753 |
tag = str(p.get("tag") or "").lstrip("@").strip()
|
|
@@ -767,15 +773,17 @@ def _restore_rail_only(ref_text, pinned):
|
|
| 767 |
# and spend an attempt on a rejection the rail already had the answer
|
| 768 |
# to.
|
| 769 |
row = (by_tag.get(str(r.get("tag") or "").lstrip("@").strip())
|
| 770 |
-
or by_file.get(str(r.get("file") or "").strip())
|
| 771 |
-
|
| 772 |
-
|
|
|
|
|
|
|
|
|
|
| 773 |
for field in RAIL_ONLY_FIELDS:
|
| 774 |
value = row.get(field)
|
| 775 |
-
if
|
| 776 |
-
|
| 777 |
-
|
| 778 |
-
elif r.get(field) != value:
|
| 779 |
r[field] = value
|
| 780 |
touched = True
|
| 781 |
return json.dumps(obj, indent=2) if touched else ref_text
|
|
|
|
| 722 |
return json.dumps({"refs": refs, "subjects": subs}, indent=2)
|
| 723 |
|
| 724 |
|
| 725 |
+
# Fields the RAIL owns and the writer never authors. `mp` is a pixel budget the
|
| 726 |
+
# person sets per row; it is absent from the valid-fields list in
|
| 727 |
+
# SYSTEM_PROMPT.md and the schema tells the model not to author it. Accept
|
| 728 |
+
# writes the returned register straight onto the rail, so without this a Write
|
| 729 |
+
# plan silently reset every cap to "full": chain_00047 ran three plates at
|
| 730 |
+
# 0.54 MP (1.58 MP total against a 0.72 MP canvas) and the next write put the
|
| 731 |
+
# same three back at native size, 3.23 MP, which is the run that came back with
|
| 732 |
+
# the reference photograph rendered instead of the beat.
|
| 733 |
RAIL_ONLY_FIELDS = ("mp",)
|
| 734 |
|
| 735 |
|
|
|
|
| 740 |
REMOVED, it is not left as the model wrote it. `mp` is exposed in the
|
| 741 |
schema so a hand-authored plan can set one, which means a model can put a
|
| 742 |
number there too -- gemma4-26b read the units as pixels and returned
|
| 743 |
+
1000000000, then -1, then 1e+15.
|
| 744 |
+
|
| 745 |
+
Runs with an EMPTY rail as well, which is the whole point: `mp` is not the
|
| 746 |
+
writer's field whether or not there are rows to restore from. Gated on
|
| 747 |
+
`pinned` it no-opped on a brief-only write, the invented value reached
|
| 748 |
+
`parse_ref_plan`, and that raises -- which short-circuits every other check
|
| 749 |
+
in `validate`, so all three attempts died on one line about megapixels and
|
| 750 |
+
the missing files were never reported at all.
|
| 751 |
"""
|
| 752 |
obj = _parse_obj(ref_text)
|
| 753 |
+
if not isinstance(obj, dict):
|
| 754 |
return ref_text
|
| 755 |
by_tag, by_file = {}, {}
|
| 756 |
+
for p in (pinned or []):
|
| 757 |
if not isinstance(p, dict):
|
| 758 |
continue
|
| 759 |
tag = str(p.get("tag") or "").lstrip("@").strip()
|
|
|
|
| 773 |
# and spend an attempt on a rejection the rail already had the answer
|
| 774 |
# to.
|
| 775 |
row = (by_tag.get(str(r.get("tag") or "").lstrip("@").strip())
|
| 776 |
+
or by_file.get(str(r.get("file") or "").strip())
|
| 777 |
+
or {})
|
| 778 |
+
# Note the order: DROP first, then set from the rail if it has one. No
|
| 779 |
+
# `continue` on a missing row -- a ref the rail knows nothing about is
|
| 780 |
+
# exactly the case where the model's own number is the only one there,
|
| 781 |
+
# and it is still not the model's field to set.
|
| 782 |
for field in RAIL_ONLY_FIELDS:
|
| 783 |
value = row.get(field)
|
| 784 |
+
if r.pop(field, None) is not None:
|
| 785 |
+
touched = True
|
| 786 |
+
if value not in (None, "", 0):
|
|
|
|
| 787 |
r[field] = value
|
| 788 |
touched = True
|
| 789 |
return json.dumps(obj, indent=2) if touched else ref_text
|
|
@@ -454,6 +454,22 @@ def main():
|
|
| 454 |
ck("an unrenamed tag is matched by filename",
|
| 455 |
"mp" not in byfile["refs"][0], f"got {byfile['refs'][0].get('mp')!r}")
|
| 456 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 457 |
bad = json.dumps({"refs": [{"tag": "ref_1", "file": "cook_face.png",
|
| 458 |
"retention": "reference", "desc": "a face",
|
| 459 |
"mp": 1000000000}], "subjects": {}})
|
|
|
|
| 454 |
ck("an unrenamed tag is matched by filename",
|
| 455 |
"mp" not in byfile["refs"][0], f"got {byfile['refs'][0].get('mp')!r}")
|
| 456 |
|
| 457 |
+
# ...and with an EMPTY rail, which is a brief-only write. Gated on `pinned`
|
| 458 |
+
# this no-opped, the invented value reached parse_ref_plan, and that RAISES
|
| 459 |
+
# -- short-circuiting every other check, so three attempts died on one line
|
| 460 |
+
# about megapixels and the missing files were never reported. Live: -1,
|
| 461 |
+
# then 1e+15, from gemma4-26b on 2026-09-02.
|
| 462 |
+
invented = json.dumps({"refs": [
|
| 463 |
+
{"tag": "influencer_face", "file": "ref_1.jpg", "subject": 1,
|
| 464 |
+
"desc": "a face", "mp": -1},
|
| 465 |
+
{"tag": "platform", "file": "ref_2.jpg", "retention": "reference",
|
| 466 |
+
"desc": "a platform", "mp": 1e15}], "subjects": {}})
|
| 467 |
+
for label, pin in (("with an empty rail", []), ("with no rail at all", None)):
|
| 468 |
+
got = json.loads(PL._restore_rail_only(invented, pin))
|
| 469 |
+
ck(f"an invented `mp` is dropped {label}",
|
| 470 |
+
all("mp" not in r for r in got["refs"]),
|
| 471 |
+
repr([r.get("mp") for r in got["refs"]]))
|
| 472 |
+
|
| 473 |
bad = json.dumps({"refs": [{"tag": "ref_1", "file": "cook_face.png",
|
| 474 |
"retention": "reference", "desc": "a face",
|
| 475 |
"mp": 1000000000}], "subjects": {}})
|