The chair-feedback chain was DEAD: 27 feedback rows captured, 0 ever became a
lesson the writer reads (no weekly-analysis job ever existed). The chair's own
corrections — the most authoritative signal of all, and exactly "learn from every
returned draft" — went nowhere.
decision_lessons can't carry them: it's FK-coupled to a style_corpus row (a signed
final), which a case-in-progress doesn't have. So chair STYLE feedback instead
rides the discussion_rules channel that already reaches the writer for all blocks —
the same path /training promote uses.
- db.append_global_rule: the locked read-modify-write append, extracted from web
`_append_methodology_override` into one shared impl (G2). The web function is now
a thin wrapper that seeds defaults; chair-feedback calls it directly.
- record_chair_feedback (MCP tool): a STYLE-category correction (style/wrong_tone/
wrong_structure) with a lesson_extracted flows immediately to discussion_rules.
The chair IS the gate — no separate approval (INV-LRN1 graduated gate). SUBSTANCE
feedback (missing_content/factual_error/other) is case-specific → recorded only.
Invariants: INV-LRN1 (chair-authored style = highest authority, flows; substance
not auto-flowed), G2 (single append impl shared by promote + feedback), INV-LRN5
(style channel only).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>