MCPcopy Create free account
hub / github.com/917Dhj/DeepPaperNote / validate_note_plan

Function validate_note_plan

scripts/lint_grounding.py:197–258  ·  view source on GitHub ↗
(
    note_plan: dict[str, Any],
    source_manifest: dict[str, Any],
)

Source from the content-addressed store, hash-verified

195
196
197def validate_note_plan(
198 note_plan: dict[str, Any],
199 source_manifest: dict[str, Any],
200) -> list[dict[str, Any]]:
201 issues: list[dict[str, Any]] = []
202 for field in NOTE_PLAN_REQUIRED_FIELDS:
203 if field not in note_plan:
204 issues.append(issue("note_plan_required_field_missing", field=field))
205 for field in NOTE_PLAN_STRING_FIELDS:
206 if field in note_plan and not normalize_whitespace(str(note_plan.get(field, ""))):
207 issues.append(issue("note_plan_required_field_empty", field=field))
208 for field in NOTE_PLAN_LIST_FIELDS:
209 value = note_plan.get(field)
210 if field in note_plan and (not isinstance(value, list) or not value):
211 issues.append(issue("note_plan_required_field_empty", field=field))
212
213 paper_type = normalize_whitespace(str(note_plan.get("paper_type", "")))
214 if paper_type not in PAPER_TYPE_VALUES:
215 issues.append(issue("note_plan_paper_type_invalid", paper_type=paper_type))
216
217 if source_is_truncated(source_manifest) and not accepts_partial_reading(note_plan):
218 issues.append(issue("source_manifest_truncated_without_partial_acceptance"))
219
220 valid_ids = source_section_ids(source_manifest)
221 max_page = total_pages(source_manifest)
222 required_sections = set(WRITING_CONTRACT_RULES["grounding_required_sections"])
223 grounded_sections: set[str] = set()
224 section_plan = note_plan.get("section_plan", [])
225 if not isinstance(section_plan, list):
226 issues.append(issue("note_plan_section_plan_invalid"))
227 return issues
228
229 for item in section_plan:
230 if not isinstance(item, dict):
231 issues.append(issue("note_plan_section_plan_item_invalid"))
232 continue
233 section_name = normalize_whitespace(
234 str(item.get("section") or item.get("name") or item.get("heading") or "")
235 )
236 if section_name in required_sections:
237 grounded_sections.add(section_name)
238 sources = evidence_sources(item)
239 if section_name in required_sections and not sources:
240 issues.append(issue("section_plan_grounding_missing", section=section_name))
241 continue
242 if section_name in required_sections and not focus_is_substantive(
243 section_focus_text(item)
244 ):
245 issues.append(issue("section_plan_focus_too_thin", section=section_name))
246 for source in sources:
247 for code in source_grounding_errors(source, valid_ids, max_page):
248 issues.append(issue(code, section=section_name, source=source))
249
250 for section_name in sorted(required_sections - grounded_sections):
251 issues.append(issue("section_plan_required_section_missing", section=section_name))
252
253 issues.extend(validate_central_claims(note_plan, valid_ids, max_page))
254

Callers 1

mainFunction · 0.85

Calls 12

normalize_whitespaceFunction · 0.90
source_is_truncatedFunction · 0.85
accepts_partial_readingFunction · 0.85
source_section_idsFunction · 0.85
total_pagesFunction · 0.85
evidence_sourcesFunction · 0.85
focus_is_substantiveFunction · 0.85
section_focus_textFunction · 0.85
source_grounding_errorsFunction · 0.85
validate_central_claimsFunction · 0.85
contains_old_referenceFunction · 0.85
issueFunction · 0.70

Tested by

no test coverage detected