portfolio-optimiser/tests/test_frontmatter_unquote_loadbearing.py
Kjell Tore Guttormsen fbc7a6120a fix(okf): one unquoting rule for frontmatter scalars (kø-(a)/(i))
Two rules existed. verdicts._unquote took quotes off correctly; the
bundle_context title renderer stripped only `"`. Measured before the fix:
`title: "  Spaced  "` rendered as `## concept:   Spaced  ` (the whitespace
half kø-(a) named), and `title: 'Single'` rendered its quotes verbatim —
both ordinary YAML a hand-authoring curator writes, and both reach the
agent's read-context.

The (p) defect class: a duplicated conversion drifts, and the drifted copy
decides something. Same fix shape — ONE source, owned by the module that
owns parse_frontmatter. okf.unquote_scalar is now the rule; verdicts
delegates by identity, so the structural key that _mint_id hashes is
unchanged.

The commons-owned nav-goldens could never have caught this: every golden
title is double-quoted with no inner whitespace, so both rules render them
byte-identically. That is asserted as a control, and it goes RED if a
future golden gains a discriminating title.

Load-bearing MEASURED against the whole suite, three mutations:
- weaken the renderer back to .strip('"') -> ONLY the 2 new rows red,
  643 others green (incl. nav-goldens) = it covers ground nothing did
- reintroduce a private _unquote copy in verdicts -> only the identity
  test red, 644 green (the copy is behaviourally identical TODAY, which
  is exactly why identity is the only thing that catches the class)
- (control, kø-(n)) add `import numpy` to a second src module -> the
  existing test_semretrieval_is_the_sole_numpy_importer goes red alone,
  confirming that gate is live rather than green-but-dead

638 -> 645 tests.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DVMsih6tXx39VMyq6wJ5H7
2026-08-04 21:23:18 +02:00

109 lines
5 KiB
Python

"""Kø-(a)/(i) — ONE unquoting rule for frontmatter scalars, and it renders the read-context.
Two rules existed. ``verdicts._unquote`` (``.strip().strip('"').strip("'").strip()``) unquoted the
structural key correctly; ``okf.bundle_context`` unquoted a title with a bare ``.strip('"')``. The
weaker one sat in the path that becomes the agent's read-context and that the commons-owned
nav-goldens byte-compare. Measured before the fix:
title: " Spaced " -> ``## concept: Spaced `` (the whitespace half — what (a) named)
title: 'Single' -> ``## concept: 'Single'`` (single quotes rendered verbatim)
Both are frontmatter YAML writes any hand-authoring curator may make, and both reach the model.
This is the (p) defect class — two copies of one conversion, the drifted copy where it matters —
so the fix is the same shape: ONE source, owned by the module that owns ``parse_frontmatter``.
Detach points, each its own test: weaken the renderer back to ``.strip('"')`` -> RED; reintroduce
a private copy in ``verdicts`` -> RED. The control proves the gate covers ground the nav-goldens
do not: every golden title is double-quoted with no inner whitespace, so the goldens stay byte-
identical under BOTH rules and can never have caught this.
"""
from __future__ import annotations
from pathlib import Path
import pytest
from portfolio_optimiser import okf
from portfolio_optimiser import verdicts as verdicts_mod
_GOLDEN_ROOT = Path(__file__).resolve().parents[1] / "shared" / "examples"
def _bundle(tmp_path: Path, title_line: str) -> str:
"""A minimal two-file bundle whose single concept file carries ``title_line`` verbatim."""
(tmp_path / "index.md").write_text(
'---\ntype: index\ntitle: "Root"\n---\n\nSummary.\n\n- [A](a.md)\n',
encoding="utf-8",
)
(tmp_path / "a.md").write_text(
f"---\ntype: concept\n{title_line}\n---\n\nbody a\n", encoding="utf-8"
)
return str(tmp_path)
def _heading(bundle_dir: str) -> str:
ctx = okf.bundle_context(okf.navigate_bundle(bundle_dir))
return next(line for line in ctx.splitlines() if line.startswith("## "))
@pytest.mark.parametrize(
("title_line", "expected"),
[
('title: " Spaced "', "## concept: Spaced"),
("title: 'Single'", "## concept: Single"),
('title: "Plain"', "## concept: Plain"),
("title: Bare", "## concept: Bare"),
],
)
def test_rendered_title_is_unquoted_and_trimmed(
tmp_path: Path, title_line: str, expected: str
) -> None:
"""The rendered heading carries the TITLE, not the frontmatter's quoting artifacts.
Detach point: revert ``bundle_context`` to ``.strip('"')`` -> the first two rows go RED
(``## concept: Spaced `` and ``## concept: 'Single'``). The last two rows are the control
that the stronger rule did not change the cases that already worked."""
assert _heading(_bundle(tmp_path, title_line)) == expected
def test_frontmatter_unquoting_has_exactly_one_source() -> None:
"""``verdicts`` must DELEGATE, not carry its own copy — the (p) rule applied to unquoting.
Identity, not equal behaviour: two implementations that agree today are exactly the state
this defect class starts from. Reintroduce a private copy in ``verdicts`` -> RED."""
assert verdicts_mod._unquote is okf.unquote_scalar, (
"verdicts must delegate to okf.unquote_scalar; a private copy is the defect class"
)
def test_verdict_structural_key_still_unquotes_after_delegation() -> None:
"""The delegation must be behaviour-identical on the structural key, because ``_mint_id``
hashes these values — a normalising change would re-key every promoted verdict.
Not a tautology against the source: the expected values are written out longhand here."""
assert okf.unquote_scalar('" Spaced "') == "Spaced"
assert okf.unquote_scalar("'Single'") == "Single"
assert okf.unquote_scalar(" bare ") == "bare"
assert okf.unquote_scalar('"18000"') == "18000"
def test_nav_goldens_cannot_have_caught_this() -> None:
"""CONTROL — the commons-owned byte-level fasit is blind to this defect by construction.
Every golden title is double-quoted with no inner whitespace, so ``.strip('"')`` and
``unquote_scalar`` render byte-identically there. If a future golden gains a single-quoted or
space-padded title this test goes RED and says so: the fasit would then be load-bearing for
the rule, and this file's claim to cover uncovered ground would no longer hold."""
titles = [
line.split(":", 1)[1].strip()
for path in sorted(_GOLDEN_ROOT.glob("nav-golden-*/**/*.md"))
for line in path.read_text(encoding="utf-8").splitlines()
if line.startswith("title:")
]
assert titles, "no golden titles found — the control has lost its subject"
for raw in titles:
assert raw.strip('"') == okf.unquote_scalar(raw), (
f"golden title {raw!r} now discriminates between the two rules — the nav-goldens "
"have become load-bearing for unquoting, so this control must be re-stated"
)