.. meta::
   :description: POST AA b23 --- The matheo floor pour rewrites its target pages wholesale and used to destroy hand-curation silently. A guard now refuses to do that. This is the register of what is generated, what is still hand-written, and what must happen before the next pour.
   :keywords: AnyAims, POST AA b23, matheo floor, gen-matheo-floor, curation guard, hand-curation, WorkInProgress, silent data loss, pour procedure

.. _post-aa-b23-matheo-floor-pour-curation-guard:


****************************************************************************************
POST AA b23: the floor pour destroys hand-curation --- guard, and register
****************************************************************************************

| **VVN:** ``aa-b23-floor-pour-guard-dv_ClaOp50Max_MMv1r0p0_2026m09d11_17h05``
| **Status:** OPEN (2)
| **Scope:** ``scripts/gen-matheo-floor.py`` and every page it writes --- the eleven
  ``source/study/matheo/bNN/index.rst`` choosers and ``source/study/matheo/index.rst``.
| **Origin:** LLoL, 2026m09d11, on being told that a newly added section would be destroyed
  by the next pour: *"can you create some AA entry and a hook and memory in the py script
  for moving matheo papers and pooring floors etc such that all the manual changes get
  reviewed and either integrated into the script or somehow be remembered?"*
  Full record: :ref:`hell-ll-infra-b47-push-readiness-audit-llog`.


The failure this exists to stop
=================================

``gen_chooser()`` and ``gen_index()`` rewrite their target files **wholesale**. Anything a
human added between two pours was destroyed, **silently, with exit code 0**. The script
already warned about this in a comment written 2026m07d16 --- *"Anything hand-added to a
chooser is destroyed at the next pour, silently"* --- and the warning was correct and was
not enough, because nothing enforced it.

**Measured on 2026m09d11, before the guard existed**, a pour would have destroyed **104
lines** across three pages, including:

- the **four overview doors** section on the series index --- the flagship new content of
  that week's work;
- the *"eleven studies at a glance"* section and its ``matheo-overview-glance`` include;
- the **How to cite** line;
- the hand-condensed three-bullet on-ramp summaries;
- both freshly written *"where the live draft lives"* pointers on b15 and b16.

None of it would have produced an error, a warning, or a non-zero exit.


What was done
===============

**1. A guard (the hook).** ``write_guarded()`` in ``scripts/gen-matheo-floor.py`` compares
every target file on disk with the text about to replace it. Any non-blank line present on
disk and absent from the new text is treated as hand-curation. If any are found the pour
**stops**, prints them, rescues them to ``AHA/HH/matheo-floor-rescued-*.rst``, and exits 1.

.. list-table::
   :header-rows: 1
   :widths: 34 66

   * - Command
     - Behaviour
   * - ``make matheo-floor-check``
     - Reports what a pour would destroy. **Writes nothing at all** --- not even a rescue
       file, because nothing is at risk during a dry run. Run it before every pour, and
       before hand-editing any generated page.
   * - ``make matheo-floor``
     - Pours, but **refuses** any file where curation would be lost, after rescuing it.
   * - ``… MATHEO_FLOOR_ARGS=--accept-curation-loss``
     - Pours anyway. The rescue copy is still written. For genuinely obsolete content only.

**2. Integration (the preferred fix).** Content that belongs to the generator was moved
*into* it, so it is emitted rather than hand-maintained:

- ``DOORS`` --- the four overview doors, now generated on the series index.
- The *"eleven studies at a glance"* section, the glance include and the **How to cite**
  line --- now generated.
- ``WorkInProgress`` --- gained a ``b15`` entry, and its ``b16`` entry was updated from the
  stale OOv2 to OOv3 plus the b16-extra companion. One registry now feeds **both** the
  per-paper chooser and a new generated *"Where improvements accumulate"* section on the
  series index, so the two can no longer drift apart.
- ``pdf`` in a ``WorkInProgress`` entry became **optional**. It had been mandatory, which is
  how the b16 chooser came to advertise *"Download OOv3 (PDF, 47 pages)"* for a file that was
  never committed. An entry must now omit the key rather than promise a missing file.

That reduced the series index's exposure from **68 lost lines to 37**.


Task list
=============

.. list-table::
   :header-rows: 1
   :widths: 5 5 40 50

   * - k
     - s
     - Task
     - Notes
   * - k4
     - s2
     - **Decide the fate of the hand-condensed on-ramp summaries (37 lines).**
     - This is the whole of the remaining exposure on ``source/study/matheo/index.rst``. The
       two on-ramp entries carry **three tight hand-written bullets each**; the generator
       re-extracts the raw ``**Abstract**`` from the source paper, which is roughly five
       times longer and reads as raw prose. **A pour would replace polished editorial work
       with a raw extraction** --- a visible regression, which is exactly why the guard
       refuses. Three ways out: (a) add an ``ONRAMP_SUMMARY`` registry to the script and
       generate them, mirroring ``DOORS`` --- preferred; (b) teach ``extract_block`` to
       prefer a short summary block if the source paper carries one; (c) leave them manual
       and restore them after each pour, which is what this AA entry currently makes
       possible but not safe.
   * - k3
     - s2
     - **Pour once, so the choosers stop being hand-written.**
     - ``b15/index.rst`` and ``b16/index.rst`` still carry **hand-written** pointer
       admonitions, while the same content now also lives in ``WorkInProgress``. Both say the
       same thing today; nothing keeps them saying it tomorrow. A pour would replace the
       hand-written text with the generated text and end the duplication --- but it cannot
       run cleanly until the row above is settled, because the same pour touches the index.
       **Until then, edit the wording in the script, not on the page.**


Rules that now hold
=====================

1. **Never hand-edit a page this script writes.** Every such page carries
   ``.. (generated by scripts/gen-matheo-floor.py --- do not hand-edit; edit the script.)``.
   The guard is a safety net, not permission.
2. **Run** ``make matheo-floor-check`` **before a pour**, and before hand-editing any
   generated page --- it says in seconds what is at stake.
3. **A rescue file in** ``AHA/HH/`` **means work was nearly lost.** Read it, integrate or
   record its contents, then delete it. It is not an archive to accumulate.
4. **Prefer integration to memory.** This register exists for what genuinely cannot be
   generated; anything that can be, should be.
