@@ -835,9 +835,18 @@ def _slugify(s: str) -> str:
835835 them to you. These are NOT discretionary — propose an action to repair \
836836 each one. They take priority over salience-driven proposals.
837837
838- Each task names a ``file`` (relative to ``knowledge/``), a broken ``target`` \
839- (the wikilink that does not resolve), and a ``context`` snippet showing \
840- where it appears. For EACH broken-wikilink task, do this:
838+ Each task names a ``kind`` (the invariant type), a ``file`` (relative to \
839+ ``knowledge/`` — for an over-cap dir this is the directory), a ``target`` \
840+ (the offending value, interpreted per kind), and a ``context`` snippet. \
841+ ALWAYS set ``salience_signal: null`` on a repair proposal — these are \
842+ integrity fixes, not salience judgments, and the Scholar will \
843+ verify-and-execute them rather than judge them for novelty. In \
844+ ``reasoning``, quote the task's ``file`` and ``target`` and state which fix \
845+ you chose and why. Dispatch on ``kind``:
846+
847+ ──────────────────────────────────────────────────────────────────
848+ kind: broken_wikilink (``target`` = the wikilink that does not resolve)
849+ ──────────────────────────────────────────────────────────────────
841850
842851 1. **Research the intended target.** The broken target usually got the \
843852 PATH wrong, not the concept. Run ``mcp__agent_mem_library__bm25_search`` \
@@ -863,15 +872,61 @@ def _slugify(s: str) -> str:
863872 the link or replace it with plain descriptive text), preserving the rest \
864873 of the prose. Explain in ``reasoning`` why no target should exist.
865874
866- 3. In ``reasoning``, quote the task's ``file`` and ``target`` and state \
867- which of the three fixes you chose and why (cite the entry you found, or \
868- state that no entry exists). Set ``salience_signal: null`` for repair \
869- proposals — they are integrity fixes, not salience judgments.
870-
871875Do the link research with the SAME parallel-search discipline as for \
872876 dedup. A repair proposal that guesses the path without searching will \
873877 likely be vetoed.
874878
879+ ──────────────────────────────────────────────────────────────────
880+ kind: overcap_dir (``file``/``target`` = the over-capacity directory)
881+ ──────────────────────────────────────────────────────────────────
882+
883+ The directory holds more than 5 entry .md files and must be rebalanced. \
884+ The ``context`` lists every entry currently in it.
885+
886+ 1. **Read the entries** (or their frontmatter ``title``/``keywords`` from \
887+ the snapshot) to find the natural thematic groupings. Use the existing \
888+ sub-structure of sibling folders as a guide for sensible subfolder names.
889+
890+ 2. **Propose exactly ONE rebalancing action:**
891+ - **The entries split into 2+ coherent themes** → ``split_folder`` on \
892+ ``folder_path`` = the over-cap dir, with ``into`` mapping each new \
893+ subfolder NAME → the list of entry paths (relative to ``knowledge/``) that \
894+ move there. Leave no destination subfolder over 5; entries you don't list \
895+ stay put (so the remainder must also be ≤5). The Scholar's \
896+ ``move_entries`` call rewrites all inbound wikilinks atomically.
897+ - **A few entries clearly belong in an EXISTING sibling folder** → one \
898+ ``move_entry`` per such entry (``from_path`` → ``to_path``) until the dir \
899+ is back at or below 5. Prefer this when only one or two entries are \
900+ outliers and the rest are cohesive.
901+
902+ 3. Choose subfolder names that read well as a path \
903+ (``global/python/testing/`` not ``global/python/misc-2/``). Do NOT propose \
904+ a split that just shards the dir into ``part-1``/``part-2`` — the grouping \
905+ must be meaningful.
906+
907+ ──────────────────────────────────────────────────────────────────
908+ kind: bad_frontmatter (``file``/``target`` = the entry with bad frontmatter)
909+ ──────────────────────────────────────────────────────────────────
910+
911+ The entry's YAML frontmatter is missing, unparseable, or short the \
912+ required fields (``context`` names the exact defect). The body content is \
913+ fine — only the frontmatter block needs repair.
914+
915+ 1. **Read ``file``** to recover its current frontmatter (whatever is \
916+ salvageable) and its full body.
917+
918+ 2. **Propose an ``update_entry``** on ``file`` whose ``new_body`` is the \
919+ entry's UNCHANGED body preceded by a corrected frontmatter block that \
920+ re-serialises valid YAML with EVERY required field present: ``id`` \
921+ (kebab-case matching the filename), ``type``, ``scope`` (consistent with \
922+ the path — ``global`` under ``global/``, ``project:<slug>`` under \
923+ ``projects/<slug>/``), ``status``, ``confidence``, ``applies-when``, \
924+ ``keywords``, ``title``, ``created``, ``updated``, ``fired``, \
925+ ``fired-helpful``, ``sources``. Preserve any existing valid values; fill \
926+ missing fields from the body's content and sensible defaults (e.g. \
927+ ``status: provisional``, ``confidence: 0.6``, ``fired: 0``, \
928+ ``fired-helpful: 0``). Do NOT rewrite the body prose.
929+
875930═══════════════════════════════════════════════════════════════════
876931HIERARCHY INVARIANTS (the Scholar will veto violations)
877932═══════════════════════════════════════════════════════════════════
0 commit comments