"""Single-source-of-truth registry for prefetched-section block writes. Reviewer and implementer both register the same conceptual section list (diff, comments, CI logs, reviews, ...). The two previous ``_try(...)`` helpers drifted; this module owns the iteration so adding a new section is one edit, not two. Scope is the block-store channel only. The on-disk sentinel (:mod:`_pr_context_sentinel`) and the inline section renderers each have schema/format needs that don't unify cleanly with the others — folding them in would lose information, not save edits. """ from __future__ import annotations import sys from dataclasses import dataclass from pathlib import Path from typing import Any _TOOLS_DIR = str(Path(__file__).resolve().parent) if _TOOLS_DIR not in sys.path: sys.path.insert(0, _TOOLS_DIR) from _loader import ( # noqa: E402 type: ignore[import-not-found] load_sibling as _load_sibling, ) _block_prompt = _load_sibling("_block_prompt", "_block_prompt.py") @dataclass(frozen=True) class PrefetchSection: """One row in the section registry. ``block_type`` becomes the second component of the canonical key ``pr-{N}-{block_type}-{sha}``. ``content`` is plain text (diff / issue body) or JSON. Empty content is skipped by the registrar. ``description`` is the one-line ``## Available blocks`` cell. """ block_type: str content: str description: str def register_sections( sections: list[PrefetchSection], *, pr_number: int | None, head_sha: str | None, ) -> list[Any]: """Register every non-empty section as a block. Returns the list of :class:`_block_prompt.BlockRef` for sections that registered successfully; rows where ``content`` was empty or the block-store layer refused are silently skipped (the inline section in the prompt is still the primary source). The registrar never raises — every per-section failure is swallowed by :func:`_block_prompt.register_section_block`, which logs at WARN. Callers may wrap in a top-level try/except if the substrate itself is in doubt, but no per-section handling is needed. """ refs: list[Any] = [] for section in sections: if not section.content: continue ref = _block_prompt.register_section_block( pr_number=pr_number, head_sha=head_sha, block_type=section.block_type, content=section.content, description=section.description, ) if ref is not None: refs.append(ref) return refs __all__ = ("PrefetchSection", "register_sections")