Skip to content

Commit fbed590

Browse files
JihaoXinclaude
andcommitted
Simplify page check: enforce only at dev-phase + post-validate, log-only after writing
- Post-writing: only log page count (writer already has prompt constraint) - Dev phase initial draft: enforce (first version often too short) - Post-validate final: enforce (figure changes may alter layout) - Also pick up compiler.py fix: protect AI-generated figures from overwrite Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 4655736 commit fbed590

File tree

2 files changed

+46
-3
lines changed

2 files changed

+46
-3
lines changed

ark/compiler.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,9 +322,23 @@ def _run_figure_phase(self):
322322
self.log_step(f"No figure script at {script_path}, skipping generation", "info")
323323

324324
# Step 2.5: Generate AI concept figures (Nano Banana)
325+
# Track which files are AI-generated so the figure fixer won't touch them
326+
ai_generated_files = set()
325327
if self.config.get("figure_generation") == "nano_banana":
326328
self.log_step("Generating AI concept figures (Nano Banana)...", "progress")
329+
# Snapshot existing files before generation
330+
existing_before = {f.name for f in self.figures_dir.glob("*")}
327331
self._generate_nano_banana_figures()
332+
# Any new files are AI-generated concept figures
333+
existing_after = {f.name for f in self.figures_dir.glob("*")}
334+
ai_generated_files = existing_after - existing_before
335+
# Also include files that were already generated in earlier phases
336+
for f in self.figures_dir.glob("*.png"):
337+
if f.name.startswith("fig_") and f.name not in ai_generated_files:
338+
# Check if this was generated by PaperBanana (large, not from matplotlib)
339+
# PaperBanana PNGs are typically >100KB; matplotlib PNGs are smaller
340+
if f.stat().st_size > 150_000:
341+
ai_generated_files.add(f.name)
328342

329343
for loop in range(MAX_FIGURE_LOOPS):
330344
# Step 3: Compile and convert to images
@@ -365,6 +379,18 @@ def _run_figure_phase(self):
365379
except Exception:
366380
pass
367381

382+
# Build protected files section
383+
protected_section = ""
384+
if ai_generated_files:
385+
protected_list = "\n".join(f"- {f}" for f in sorted(ai_generated_files))
386+
protected_section = f"""
387+
### ⚠️ PROTECTED AI-Generated Concept Figures (DO NOT MODIFY)
388+
The following figures were generated by PaperBanana/Gemini AI and must NOT be
389+
overwritten, regenerated, or replaced by matplotlib. Do NOT modify any Python
390+
script to output to these filenames. Only check their LaTeX placement/sizing.
391+
{protected_list}
392+
"""
393+
368394
fixer_prompt = f"""## Figure Quality Check (Loop {loop + 1}/{MAX_FIGURE_LOOPS})
369395
370396
### Template Geometry Parameters
@@ -375,7 +401,7 @@ def _run_figure_phase(self):
375401
376402
### Current Figure Files
377403
{figures_list}
378-
{overlap_section}
404+
{protected_section}{overlap_section}
379405
### PDF Page Images (use Read tool to view each page)
380406
{images_list}
381407
@@ -409,7 +435,19 @@ def _run_figure_phase(self):
409435
elif "FIGURES_NEED_FIX" in (result or ""):
410436
self.log_step("Figure fixer made changes, will re-check...", "progress")
411437
if full_script.exists():
438+
# Back up AI-generated concept figures before re-running script
439+
backups = {}
440+
for fname in ai_generated_files:
441+
fpath = self.figures_dir / fname
442+
if fpath.exists():
443+
backups[fname] = fpath.read_bytes()
412444
self.generate_figures()
445+
# Restore any AI-generated files that were overwritten
446+
for fname, data in backups.items():
447+
fpath = self.figures_dir / fname
448+
if not fpath.exists() or fpath.read_bytes() != data:
449+
fpath.write_bytes(data)
450+
self.log(f"Restored AI-generated figure: {fname}", "INFO")
413451
else:
414452
self.log_step("Figure fixer verdict unclear, continuing...", "warning")
415453
break

ark/execution.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,8 +1025,13 @@ def _run_writing_phase(self, action_plan: dict, prior_context: str = ""):
10251025
self._save_action_plan(action_plan)
10261026
self.log_step("Writing phase completed", "success")
10271027

1028-
# Post-writing page count check: compress if over, expand if too short
1029-
self._enforce_page_count(context="post-writing")
1028+
# Page count logged for awareness (hard enforcement is in post-validate)
1029+
venue_pages = self.config.get("venue_pages")
1030+
if venue_pages and not self._quota_exhausted:
1031+
self.compile_latex()
1032+
page_count = getattr(self, '_body_page_count', 0)
1033+
if page_count:
1034+
self.log(f"Page count after writing: {page_count:.1f}/{venue_pages} body pages", "INFO")
10301035

10311036
return True
10321037
else:

0 commit comments

Comments
 (0)