Repository navigation
fix(wiki): a draft section carries a heading and a body, both text (#587) - #588
Conversation
) _validate_against_contract checked the kind's required headings and each section's body, never a section's own heading. For a kind with no required section, {"heading": " ", "body": "prose"} and {} itself passed and were written to the draft, and wiki_compile rendered the section untitled. The nested required: [heading, body] of the tool schema is documentation: the client-visible schema comes from the registered wrapper's signature, list[dict[str, Any]] | None. Both fields are now validated as non-blank text through _is_text, a section whose heading is not text is named by its index, and a blank heading no longer counts toward a required section. A number for either field returns a validation error instead of raising AttributeError (ADR-1070). A refused call still writes neither the draft nor a memo. Six of the new cases fail on the previous validator. Full suite: 8691 passed, 8 skipped. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Cz7A6goxVzfKL9NT7k4zDH
|
ZETETIC-REVIEW: APPROVE Summary
1. Is
|
…ge (#587) ADR-1070 and the CHANGELOG said `wiki_compile` rendered such a section with no title. The review of PR #588 demonstrated otherwise: core/draft_compiler.py skips a section with no heading, so the published Markdown drops it, while handlers/wiki_compile.py mirrors the draft's sections into wiki.pages.sections with no guard, leaving the prose under an empty key. The validation this PR adds is unchanged. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Cz7A6goxVzfKL9NT7k4zDH
|
Correcting one claim in the PR body, per the review above. The body said Commit 9f1efac corrects ADR-1070, its The two gaps the review names one layer down, the unguarded DB mirror and |
|
ZETETIC-REVIEW: APPROVE SummaryRe-verification of PR #588 at new head Diff scope confirmed
Claim re-verified against the two files it namesRead
Both claims are exactly what I empirically demonstrated in the previous review round (live repro: inserting a draft with Gates run (doc-only delta), from the worktree with
|
Summary
_validate_against_contract(mcp_server/handlers/wiki_refine.py) checked that every heading the kind requires is present and that no body is blank, never a section's own heading. For a kind that declares no required section,{"heading": " ", "body": "real prose"}and{}itself passed and were written to the draft, andwiki_compilethen rendered a section with no title. The nestedrequired: [heading, body]of the tool schema is documentation: the client-visible schema is derived from the registered wrapper's signature,list[dict[str, Any]] | None, so a section missing its heading is a reachable client input.Both fields are now validated as non-blank text through
_is_text. A section whose heading is not text is named by its index, a blank heading no longer counts toward a required section, and a number in either field returns a validation error instead of raisingAttributeErrorinside the handler (ADR-1070). The handler already refused a call whose sections fail validation before any write, so a refused call still touches neither the draft norwiki.memos.Found by the review of PR #586, which drove both shapes end to end on a
notedraft.Closes #587
Type of change
Test plan
tests_py/handlers/test_wiki_refine_sections.pydrives the validator directly: empty section, missing heading, blank heading, non-text heading; four body shapes including a number; a well-formed section with and without a matching required section; and a blank heading against a required one.test_a_headless_section_writes_nothing_even_without_a_contractintests_py/handlers/test_wiki_refine_confidence.pydrives the handler on SQLite with a kind contract carrying no required section, and asserts the sections column,synth_modeland the draft's memo count are unchanged.AttributeErrorthis fixes.ruff check,ruff format --check: clean.pyright mcp_server/: 0 errors.scripts/check_craftsmanship.py --base origin/main: OK.scripts/check_doc_claims.py: OK.Audit notes
Coding-standards compliance
Breaking changes
A caller that used a section as an untitled block of prose now gets a validation error. Nothing did: the tool has been registered only since #581.
Reviewer checklist
🤖 Generated with Claude Code
https://claude.ai/code/session_01Cz7A6goxVzfKL9NT7k4zDH