superlab 0.1.64 → 0.1.66
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/i18n.cjs +6 -0
- package/lib/lab_write_contract.json +4 -4
- package/package-assets/claude/commands/lab/write.md +1 -1
- package/package-assets/claude/commands/lab-write.md +1 -1
- package/package-assets/claude/commands/lab:write.md +1 -1
- package/package-assets/claude/commands/lab/357/274/232write.md +1 -1
- package/package-assets/codex/prompts/lab/write.md +1 -1
- package/package-assets/codex/prompts/lab-write.md +1 -1
- package/package-assets/codex/prompts/lab:write.md +1 -1
- package/package-assets/codex/prompts/lab/357/274/232write.md +1 -1
- package/package-assets/shared/lab/.managed/scripts/extract_reference_paper_structure.py +1200 -0
- package/package-assets/shared/lab/.managed/scripts/validate_manuscript_delivery.py +57 -0
- package/package-assets/shared/lab/.managed/scripts/validate_section_draft.py +141 -0
- package/package-assets/shared/lab/.managed/templates/reference-template-intake.md +50 -0
- package/package-assets/shared/lab/.managed/templates/write-iteration.md +27 -0
- package/package-assets/shared/skills/lab/stages/write.md +19 -0
- package/package.json +1 -1
|
@@ -149,6 +149,54 @@ def extract_table_note(text: str) -> str:
|
|
|
149
149
|
return "\n".join(line.strip() for line in text.splitlines() if line.strip().startswith("%"))
|
|
150
150
|
|
|
151
151
|
|
|
152
|
+
def extract_tabular_specs(text: str) -> list[str]:
|
|
153
|
+
return re.findall(r"\\begin\{tabular\}(?:\[[^\]]*\])?\{([^}]*)\}", text)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def extract_tabular_bodies(text: str) -> list[str]:
|
|
157
|
+
return [
|
|
158
|
+
match.group(1)
|
|
159
|
+
for match in re.finditer(
|
|
160
|
+
r"\\begin\{tabular\}(?:\[[^\]]*\])?\{[^}]*\}([\s\S]*?)\\end\{tabular\}",
|
|
161
|
+
text,
|
|
162
|
+
)
|
|
163
|
+
]
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def strip_latex_for_table_cell(cell: str) -> str:
|
|
167
|
+
cell = re.sub(r"%.*", "", cell)
|
|
168
|
+
cell = re.sub(r"\\(?:textbf|mathbf|emph)\{([^}]*)\}", r"\1", cell)
|
|
169
|
+
cell = re.sub(r"\\[A-Za-z@*]+(?:\[[^\]]*\])?", " ", cell)
|
|
170
|
+
cell = cell.replace("$", " ")
|
|
171
|
+
return cell.strip()
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def check_numeric_precision_consistency(text: str, issues: list[str], label: str):
|
|
175
|
+
for body in extract_tabular_bodies(text):
|
|
176
|
+
column_precisions: dict[int, set[int]] = {}
|
|
177
|
+
rows = re.split(r"\\\\", body)
|
|
178
|
+
for row in rows:
|
|
179
|
+
row = re.sub(r"\\(?:toprule|midrule|bottomrule|cmidrule)(?:\{[^}]*\})?", " ", row)
|
|
180
|
+
if "&" not in row:
|
|
181
|
+
continue
|
|
182
|
+
cells = [strip_latex_for_table_cell(cell) for cell in row.split("&")]
|
|
183
|
+
for index, cell in enumerate(cells):
|
|
184
|
+
matches = re.findall(r"(?<![A-Za-z])[-+]?\d+\.(\d+)", cell)
|
|
185
|
+
if not matches:
|
|
186
|
+
continue
|
|
187
|
+
column_precisions.setdefault(index, set()).update(len(match) for match in matches)
|
|
188
|
+
inconsistent_columns = [
|
|
189
|
+
str(index + 1)
|
|
190
|
+
for index, precisions in sorted(column_precisions.items())
|
|
191
|
+
if len(precisions) > 1
|
|
192
|
+
]
|
|
193
|
+
if inconsistent_columns:
|
|
194
|
+
issues.append(
|
|
195
|
+
f"{label} has inconsistent numeric precision in column(s): {', '.join(inconsistent_columns)}"
|
|
196
|
+
)
|
|
197
|
+
return
|
|
198
|
+
|
|
199
|
+
|
|
152
200
|
def detect_uppercase_abbreviations(text: str) -> set[str]:
|
|
153
201
|
return {
|
|
154
202
|
token
|
|
@@ -210,8 +258,16 @@ def check_table_file(path: Path, issues: list[str], label: str):
|
|
|
210
258
|
issues.append(f"{label} must contain a table environment")
|
|
211
259
|
if r"\caption{" not in text or r"\label{" not in text:
|
|
212
260
|
issues.append(f"{label} must contain both caption and label")
|
|
261
|
+
first_caption = text.find(r"\caption{")
|
|
262
|
+
first_tabular = text.find(r"\begin{tabular}")
|
|
263
|
+
if first_caption != -1 and first_tabular != -1 and first_caption > first_tabular:
|
|
264
|
+
issues.append(f"{label} should place its caption before the tabular body")
|
|
213
265
|
if not all(token in text for token in (r"\toprule", r"\midrule", r"\bottomrule")):
|
|
214
266
|
issues.append(f"{label} must use booktabs structure")
|
|
267
|
+
if any("|" in spec for spec in extract_tabular_specs(text)) or r"\vline" in text:
|
|
268
|
+
issues.append(f"{label} must not use vertical table rules; use booktabs spacing instead")
|
|
269
|
+
if r"\hline" in text or r"\cline" in text:
|
|
270
|
+
issues.append(f"{label} must not mix legacy \\hline/\\cline rules with booktabs tables")
|
|
215
271
|
if not all(marker in text for marker in REQUIRED_TABLE_NOTE_MARKERS):
|
|
216
272
|
issues.append(f"{label} must include a local table note scaffold")
|
|
217
273
|
caption_text = extract_caption(text)
|
|
@@ -234,6 +290,7 @@ def check_table_file(path: Path, issues: list[str], label: str):
|
|
|
234
290
|
continue
|
|
235
291
|
if value < 3.0:
|
|
236
292
|
issues.append(f"{label} sets \\tabcolsep below the safe range for paper-facing main tables")
|
|
293
|
+
check_numeric_precision_consistency(text, issues, label)
|
|
237
294
|
|
|
238
295
|
|
|
239
296
|
def check_figure_file(path: Path, issues: list[str], label: str):
|
|
@@ -91,6 +91,14 @@ def has_meaningful_field_value(value: str) -> bool:
|
|
|
91
91
|
return normalized not in {"", "-", "n/a", "na", "none", "no", "not applicable", "null", "false"}
|
|
92
92
|
|
|
93
93
|
|
|
94
|
+
def latest_write_iteration(project_root: Path) -> Path | None:
|
|
95
|
+
iteration_dir = project_root / ".lab" / "writing" / "iterations"
|
|
96
|
+
if not iteration_dir.exists():
|
|
97
|
+
return None
|
|
98
|
+
iteration_files = sorted(iteration_dir.glob("*.md"))
|
|
99
|
+
return iteration_files[-1] if iteration_files else None
|
|
100
|
+
|
|
101
|
+
|
|
94
102
|
SECTION_STYLE_WARNINGS = {
|
|
95
103
|
"abstract": [
|
|
96
104
|
(
|
|
@@ -432,6 +440,32 @@ def check_active_paper_topology(section_path: Path, issues: list[str]):
|
|
|
432
440
|
issues.extend(validate_topology_artifacts(project_root))
|
|
433
441
|
|
|
434
442
|
|
|
443
|
+
def check_reference_template_intake(section_path: Path, issues: list[str]):
|
|
444
|
+
project_root = find_project_root(section_path)
|
|
445
|
+
if project_root is None:
|
|
446
|
+
return
|
|
447
|
+
|
|
448
|
+
reference_root = project_root / ".lab" / "writing" / "reference-patterns"
|
|
449
|
+
aggregate_playbook = reference_root / "aggregate-template-playbook.md"
|
|
450
|
+
legacy_notes_root = project_root / ".lab" / "writing" / "pdf-structure-notes"
|
|
451
|
+
has_legacy_notes = legacy_notes_root.exists() and any(legacy_notes_root.glob("*"))
|
|
452
|
+
|
|
453
|
+
latest_iteration = latest_write_iteration(project_root)
|
|
454
|
+
reference_sources = ""
|
|
455
|
+
if latest_iteration:
|
|
456
|
+
iteration_text = read_text(latest_iteration)
|
|
457
|
+
reference_sources = extract_markdown_field(
|
|
458
|
+
iteration_text,
|
|
459
|
+
"Reference Template Intake",
|
|
460
|
+
"Reference sources used:",
|
|
461
|
+
)
|
|
462
|
+
|
|
463
|
+
if (has_legacy_notes or has_meaningful_field_value(reference_sources)) and not aggregate_playbook.exists():
|
|
464
|
+
issues.append(
|
|
465
|
+
"reference papers appear to be used without .lab/writing/reference-patterns/aggregate-template-playbook.md; run extract_reference_paper_structure.py and use structured section/visual templates instead of legacy pdf-structure-notes"
|
|
466
|
+
)
|
|
467
|
+
|
|
468
|
+
|
|
435
469
|
def check_abstract(text: str, issues: list[str]):
|
|
436
470
|
numbers = re.findall(r"\b\d+(?:\.\d+)?\b", text)
|
|
437
471
|
if len(numbers) > 6:
|
|
@@ -504,6 +538,100 @@ def check_method(text: str, issues: list[str]):
|
|
|
504
538
|
issues.append("method should explain the technical advantage")
|
|
505
539
|
|
|
506
540
|
|
|
541
|
+
def has_performance_claim(text: str) -> bool:
|
|
542
|
+
return contains_any(
|
|
543
|
+
text,
|
|
544
|
+
(
|
|
545
|
+
"outperform",
|
|
546
|
+
"outperforms",
|
|
547
|
+
"improve",
|
|
548
|
+
"improves",
|
|
549
|
+
"improved",
|
|
550
|
+
"gain",
|
|
551
|
+
"gains",
|
|
552
|
+
"better",
|
|
553
|
+
"stronger",
|
|
554
|
+
"superior",
|
|
555
|
+
"state-of-the-art",
|
|
556
|
+
"sota",
|
|
557
|
+
"reduce",
|
|
558
|
+
"reduces",
|
|
559
|
+
"降低",
|
|
560
|
+
"提升",
|
|
561
|
+
"优于",
|
|
562
|
+
"超过",
|
|
563
|
+
"更好",
|
|
564
|
+
"增益",
|
|
565
|
+
),
|
|
566
|
+
)
|
|
567
|
+
|
|
568
|
+
|
|
569
|
+
def has_numeric_or_table_evidence(text: str) -> bool:
|
|
570
|
+
if re.search(r"\b\d+\.\d+\b", text):
|
|
571
|
+
return True
|
|
572
|
+
if re.search(r"\b\d+(?:\.\d+)?\s*(?:%|pp|points?|AUUC|Qini|AUC|F1)\b", text, flags=re.IGNORECASE):
|
|
573
|
+
return True
|
|
574
|
+
if r"\pm" in text:
|
|
575
|
+
return True
|
|
576
|
+
return bool(
|
|
577
|
+
re.search(r"\\(?:auto|c|C)?ref\{(?:tab|fig):", text)
|
|
578
|
+
or re.search(r"\b(?:Table|Figure|Fig\.|表|图)~?\\ref\{", text)
|
|
579
|
+
)
|
|
580
|
+
|
|
581
|
+
|
|
582
|
+
def has_generic_comparator_without_anchor(text: str) -> bool:
|
|
583
|
+
generic_comparator = contains_any(
|
|
584
|
+
text,
|
|
585
|
+
(
|
|
586
|
+
"previous methods",
|
|
587
|
+
"prior methods",
|
|
588
|
+
"existing methods",
|
|
589
|
+
"several baselines",
|
|
590
|
+
"the baselines",
|
|
591
|
+
"baseline suite",
|
|
592
|
+
"previous work",
|
|
593
|
+
"prior work",
|
|
594
|
+
"现有方法",
|
|
595
|
+
"已有方法",
|
|
596
|
+
"若干基线",
|
|
597
|
+
"基线集合",
|
|
598
|
+
),
|
|
599
|
+
)
|
|
600
|
+
if not generic_comparator:
|
|
601
|
+
return False
|
|
602
|
+
if r"\cite{" in text or r"\citet{" in text or r"\citep{" in text:
|
|
603
|
+
return False
|
|
604
|
+
return not bool(re.search(r"\b[A-Z][A-Za-z0-9-]{2,}(?:\s*,\s*[A-Z][A-Za-z0-9-]{2,})+", text))
|
|
605
|
+
|
|
606
|
+
|
|
607
|
+
def has_repeated_split_protocol(text: str) -> bool:
|
|
608
|
+
return bool(
|
|
609
|
+
re.search(r"\b\d+\s+(?:random\s+)?(?:splits|seeds|runs)\b", text, flags=re.IGNORECASE)
|
|
610
|
+
or re.search(r"\bacross\s+(?:random\s+)?(?:splits|seeds|runs)\b", text, flags=re.IGNORECASE)
|
|
611
|
+
or re.search(r"\b重复\s*\d+\s*次", text)
|
|
612
|
+
)
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
def has_variance_report(text: str) -> bool:
|
|
616
|
+
return contains_any(
|
|
617
|
+
text,
|
|
618
|
+
(
|
|
619
|
+
r"\pm",
|
|
620
|
+
"standard deviation",
|
|
621
|
+
"std",
|
|
622
|
+
"confidence interval",
|
|
623
|
+
"confidence intervals",
|
|
624
|
+
"ci",
|
|
625
|
+
"variance",
|
|
626
|
+
"mean",
|
|
627
|
+
"平均",
|
|
628
|
+
"标准差",
|
|
629
|
+
"置信区间",
|
|
630
|
+
"方差",
|
|
631
|
+
),
|
|
632
|
+
)
|
|
633
|
+
|
|
634
|
+
|
|
507
635
|
def check_experiments(text: str, issues: list[str]):
|
|
508
636
|
if not contains_any(
|
|
509
637
|
text,
|
|
@@ -531,6 +659,18 @@ def check_experiments(text: str, issues: list[str]):
|
|
|
531
659
|
),
|
|
532
660
|
):
|
|
533
661
|
issues.append("experiments should include benchmark scene notes")
|
|
662
|
+
if has_performance_claim(text) and not has_numeric_or_table_evidence(text):
|
|
663
|
+
issues.append(
|
|
664
|
+
"experiment performance claims should tie to concrete metric or numeric evidence instead of prose-only claims"
|
|
665
|
+
)
|
|
666
|
+
if has_generic_comparator_without_anchor(text):
|
|
667
|
+
issues.append(
|
|
668
|
+
"experiments use generic comparator names; name the comparator family, table anchor, or citations before more polish"
|
|
669
|
+
)
|
|
670
|
+
if has_repeated_split_protocol(text) and not has_variance_report(text):
|
|
671
|
+
issues.append(
|
|
672
|
+
"repeated split or seed protocol should report variance, confidence intervals, or an explicit variance disposition"
|
|
673
|
+
)
|
|
534
674
|
|
|
535
675
|
|
|
536
676
|
def check_conclusion(text: str, issues: list[str]):
|
|
@@ -566,6 +706,7 @@ def main():
|
|
|
566
706
|
check_workflow_language_targeting(section_path, blocking_issues)
|
|
567
707
|
check_common_section_gate_risks(text, warning_issues)
|
|
568
708
|
check_section_style_policy(text, args.section, warning_issues)
|
|
709
|
+
check_reference_template_intake(section_path, warning_issues)
|
|
569
710
|
SECTION_CHECKS[args.section](text, warning_issues)
|
|
570
711
|
check_neighbor_asset_files(args.section, section_path, warning_issues)
|
|
571
712
|
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Reference Template Intake
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
- Help `/lab:write` reproduce mature paper structure from multiple reference templates.
|
|
6
|
+
- Extract section slots, paragraph roles, and table/figure functions.
|
|
7
|
+
- Reuse structure and logic only; do not copy wording, claims, metrics, or conclusions.
|
|
8
|
+
|
|
9
|
+
## Sources
|
|
10
|
+
|
|
11
|
+
- Source paths or URLs:
|
|
12
|
+
- Extraction command:
|
|
13
|
+
- Output root:
|
|
14
|
+
|
|
15
|
+
## Section Templates
|
|
16
|
+
|
|
17
|
+
- Abstract:
|
|
18
|
+
- Introduction:
|
|
19
|
+
- Related work:
|
|
20
|
+
- Method:
|
|
21
|
+
- Experiments:
|
|
22
|
+
- Experiments protocol slots:
|
|
23
|
+
- Dataset descriptions:
|
|
24
|
+
- Dataset statistics / appendix link:
|
|
25
|
+
- Split or sampling protocol:
|
|
26
|
+
- Baseline setup:
|
|
27
|
+
- Metric definitions:
|
|
28
|
+
- Implementation and tuning details:
|
|
29
|
+
- Main results:
|
|
30
|
+
- Ablations:
|
|
31
|
+
- Sensitivity or analysis:
|
|
32
|
+
- Conclusion:
|
|
33
|
+
|
|
34
|
+
## Visual/Table Templates
|
|
35
|
+
|
|
36
|
+
- Main result tables:
|
|
37
|
+
- Ablation tables:
|
|
38
|
+
- Dataset/protocol tables:
|
|
39
|
+
- Method overview figures:
|
|
40
|
+
- Result or trade-off figures:
|
|
41
|
+
- Analysis/sensitivity figures:
|
|
42
|
+
|
|
43
|
+
## Write Handoff
|
|
44
|
+
|
|
45
|
+
- Aggregate template playbook:
|
|
46
|
+
- Section template selected for this round:
|
|
47
|
+
- Visual/table template selected for this round:
|
|
48
|
+
- Multi-template reproduction plan:
|
|
49
|
+
- Current-paper evidence that will fill the template:
|
|
50
|
+
- Structure-only reuse boundary:
|
|
@@ -67,6 +67,33 @@
|
|
|
67
67
|
- Any discouraged move kept and why:
|
|
68
68
|
- Any banned move found:
|
|
69
69
|
|
|
70
|
+
## Review Issue Bundle
|
|
71
|
+
|
|
72
|
+
- Issue bundle path:
|
|
73
|
+
- New issues:
|
|
74
|
+
- Resolved issues:
|
|
75
|
+
- Open issues:
|
|
76
|
+
- Quote-backed findings recorded:
|
|
77
|
+
- Script-backed findings separated from judgment-backed findings:
|
|
78
|
+
|
|
79
|
+
## Re-Audit Status
|
|
80
|
+
|
|
81
|
+
- Previous issue bundle compared:
|
|
82
|
+
- Fully addressed root causes:
|
|
83
|
+
- Partially addressed root causes:
|
|
84
|
+
- Not addressed root causes:
|
|
85
|
+
- New root causes:
|
|
86
|
+
- Which root-cause issues block further prose polish:
|
|
87
|
+
|
|
88
|
+
## Reference Template Intake
|
|
89
|
+
|
|
90
|
+
- Reference sources used:
|
|
91
|
+
- Aggregate template playbook:
|
|
92
|
+
- Section templates consulted:
|
|
93
|
+
- Visual/table templates consulted:
|
|
94
|
+
- Multi-template reproduction plan:
|
|
95
|
+
- Structure-only reuse boundary:
|
|
96
|
+
|
|
70
97
|
## Table Semantics
|
|
71
98
|
|
|
72
99
|
- Metrics promised in Method:
|
|
@@ -113,6 +113,15 @@ Run these on every round:
|
|
|
113
113
|
- Load only the current section guide. Do not load every section guide at once.
|
|
114
114
|
- Reuse example-bank structure, paragraph roles, sentence logic, and paper-facing LaTeX asset patterns when examples are bundled, but never copy wording verbatim.
|
|
115
115
|
- Treat example cites and example file names as writing references, not as evidence for the current paper.
|
|
116
|
+
- When the user provides local PDFs, PDF URLs, HTML pages, or reference papers while invoking `/lab:write`, run `.lab/.managed/scripts/extract_reference_paper_structure.py --output-dir .lab/writing/reference-patterns <sources...>` before drafting unless an up-to-date `.lab/writing/reference-patterns/aggregate-template-playbook.md` already covers those exact sources.
|
|
117
|
+
- Treat reference-paper intake as an internal write capability, not a separate user command. The user should still only need `/lab:write`; do not ask them to learn another workflow.
|
|
118
|
+
- The purpose of reference-paper intake is to help `/lab:write` reproduce mature multi-template writing structure: section slots, paragraph roles, argument sequence, table and figure functions, placement logic, and bridge sentences.
|
|
119
|
+
- Use at least two compatible reference templates when available. If only one reference is available, mark it as a single-template pattern and avoid treating it as a universal standard.
|
|
120
|
+
- For every reference table or figure, extract what reader question it answers, which section/subsection it supports, why it is placed there, what the prose before it should do, and what the prose after it should explain.
|
|
121
|
+
- When drafting from reference templates, reproduce structure and logic only. Do not copy wording, claims, metrics, baselines, data, captions, or conclusions from reference papers.
|
|
122
|
+
- Before drafting a section from reference templates, read `.lab/writing/reference-patterns/aggregate-template-playbook.md`, the matching file under `.lab/writing/reference-patterns/section-templates/`, and the matching visual/table template under `.lab/writing/reference-patterns/visual-templates/` when the section uses tables or figures.
|
|
123
|
+
- For experiment sections, also read `.lab/writing/reference-patterns/section-templates/experiments-protocol.json` when it exists and preserve its protocol slot logic: dataset descriptions, dataset statistics, split/sampling protocol, baseline setup, metric definitions, implementation or tuning details, main results, ablations, sensitivity analysis, and appendix-to-main links.
|
|
124
|
+
- Do not accept coarse labels such as “setup” or “overall performance” as a complete experiment-template extraction when the source papers contain explicit dataset, baseline, metric, implementation, or appendix-detail paragraphs.
|
|
116
125
|
- Build a compact mini-outline before prose.
|
|
117
126
|
- Academic readability standards are the same in `workflow_language` and `paper_language`; changing languages must not lower external-reader clarity.
|
|
118
127
|
- If the current round introduces or revises key terms, abbreviations, metric names, mechanism names, or system labels, explain them at first mention by briefly stating what they are and why they matter here.
|
|
@@ -126,6 +135,10 @@ Run these on every round:
|
|
|
126
135
|
- Before any additional tighten, compress, or polish pass on the same section, run a section-level acceptance gate first.
|
|
127
136
|
- The section-level acceptance gate is passed only when canonical naming consistency, adjacent-section consistency, claim, metric, and ranking consistency with the current evidence, local clarity, local concision, and section-style compliance are all explicitly checked and no unresolved blocker remains.
|
|
128
137
|
- If the current section still contains a banned expression or banned rhetorical move from `section-style-policies.md`, the round has not passed the section-level acceptance gate.
|
|
138
|
+
- If reviewer notes, validator warnings, or prior write rounds produced issues, record them as a review issue bundle in the write-iteration artifact before further polishing.
|
|
139
|
+
- Review issue bundles should separate script-backed findings from judgment-backed findings, preserve the source quote or local pointer when available, and track whether each issue is new, resolved, open, or superseded.
|
|
140
|
+
- Before continuing prose polish after a review issue bundle exists, run a re-audit pass that compares the current draft against previous root causes and records fully addressed, partially addressed, not addressed, and newly introduced root causes.
|
|
141
|
+
- Do not answer a review issue by merely changing wording around it. Fix the underlying section structure, evidence support, terminology definition, or asset/table linkage that caused the issue.
|
|
129
142
|
- If the current round changes the paper's canonical experiment or evaluation protocol (for example split ratio, train/test size, seed or split count, benchmark set, or main-table evaluation contract), treat it as a canonical protocol replacement unless the user explicitly scopes it as supplementary or appendix-only.
|
|
130
143
|
- A canonical protocol replacement requires a paper-wide impact audit before more polishing: identify stale sections and assets across Abstract, Introduction, Method, Experiments, Conclusion, tables, figures, analysis assets, and `.lab/writing/plan.md`, then update the plan and highest-impact stale targets first.
|
|
131
144
|
- When a paper-wide impact audit is still open, default the next write action to the highest-impact canonical stale section or asset instead of polishing the same section again.
|
|
@@ -163,6 +176,7 @@ Run these on every round:
|
|
|
163
176
|
- During ordinary draft rounds, run `.lab/.managed/scripts/validate_section_draft.py --section <section> --section-file <section-file> --mode draft` and `.lab/.managed/scripts/validate_paper_claims.py --section-file <section-file> --mode draft` after revising the active section.
|
|
164
177
|
- Treat draft-round output from the section and claim validators as warnings that must be recorded and addressed in the write-iteration artifact, not as immediate stop conditions.
|
|
165
178
|
- If the active section already lives under a paper-layer `sections/` directory, the draft section validator should also warn when the neighboring required figure or analysis placeholder files are still missing from that same paper layer.
|
|
179
|
+
- For experiment sections, treat prose-only performance claims, unnamed generic comparator phrases, repeated split/seed protocols without variance disposition, and result paragraphs without concrete metric/table anchors as section warnings that must be fixed before more prose-only polishing.
|
|
166
180
|
- For each subsection, explicitly include motivation, design, and technical advantage when applicable.
|
|
167
181
|
- Avoid a writing style that reads like incremental patching of a naive baseline.
|
|
168
182
|
- Keep terminology stable across the full paper.
|
|
@@ -183,6 +197,9 @@ Run these on every round:
|
|
|
183
197
|
- `<deliverables_root>/paper/analysis/analysis-asset.tex`
|
|
184
198
|
- Table assets must use paper-facing LaTeX structure with `booktabs`, caption, label, and consistent precision.
|
|
185
199
|
- Table assets must also include a local table note that explains row meaning, column meaning, metric definitions, comparison scope, and any important caveat.
|
|
200
|
+
- Table assets must avoid vertical rules, `\hline`, and `\cline`; use `booktabs` rules and whitespace instead.
|
|
201
|
+
- Table captions should appear before the tabular body so the table can be read top-down in manuscript order.
|
|
202
|
+
- Numeric precision should be consistent within each metric column unless the table note explains a deliberate exception.
|
|
186
203
|
- Table assets must not rely on aggressive width hacks by default; if width control is still needed after table redesign, document it locally and keep it readable.
|
|
187
204
|
- Figure placeholders must explain what the final figure should show and why the reader needs it.
|
|
188
205
|
- Core asset coverage for a paper-facing final draft should include a problem-setting or teaser figure, a method overview figure, a results overview figure, a main-results table, an ablation table, and one additional analysis asset.
|
|
@@ -200,6 +217,8 @@ Run these on every round:
|
|
|
200
217
|
- When a round introduces or revises key terms, include a compact terminology note in the user-facing round summary and record the terminology-clarity self-check in the write-iteration artifact.
|
|
201
218
|
- Record the section-level acceptance gate in the write-iteration artifact before recommending further tightening on the same section.
|
|
202
219
|
- Record section-style policy compliance, any retained discouraged move, and any banned move found in the write-iteration artifact.
|
|
220
|
+
- Record the review issue bundle and re-audit status in the write-iteration artifact whenever the round follows reviewer notes, validator warnings, or prior failed writing rounds.
|
|
221
|
+
- Record the reference template intake in the write-iteration artifact whenever the round uses PDFs, URLs, or `.lab/writing/reference-patterns/` artifacts: sources used, aggregate playbook path, section templates consulted, visual/table templates consulted, multi-template reproduction plan, and structure-only reuse boundary.
|
|
203
222
|
- Record the round target layer in the write-iteration artifact as `canonical manuscript`, `workflow-language paper layer`, or `both`.
|
|
204
223
|
- If workflow-language was active and the round still targeted the canonical manuscript, record why canonical-only writing was acceptable in the write-iteration artifact.
|
|
205
224
|
- If both layers were edited, record why the cross-language sync was required and whether it was explicitly requested by the user or required by final-draft/export finalization.
|