writing-for-agents: conversational synthesis violates rubric on first pass
### Before filing - [x] I've read `SCOPE.md` and checked `.out-of-scope/`, and this isn't covered by either. - [x] This issue is about one problem. - [x] I searched open and closed issues for a duplicate. ### Skill writing-for-agents ### What went wrong **Setup:** Running Gemini 3.8 Flash / Gemini 4 Argon in PI Coding Agent. **Observed failure:** When `writing-for-agents` is invoked at the end of a conversation to capture decisions into an always-loaded document (e.g. `AGENTS.md` / `CLAUDE.md`), it repeatedly emits wording that violates the skill's own rubric—most notably **Negation**, **Exposition**, and **Single Source of Truth**. Yet, when running the skill on that exact same document in a fresh session without conversational context, the model immediately recognizes and calls out those exact violations, rewriting the text to be ~60% more compact and compliant. #### Example: Interactive update vs. fresh review 1. **In-session generation (capturing a discussion on contract boundaries and testing):** The skill produced: ```markdown * **Contract-First & Lean**: Trust internal framework contracts and type guarantees past external boundaries. * **Type Narrowing via Assertions**: To satisfy static analysis on untyped structures (e.g., event contexts), narrow types using `assert($var instanceof ExpectedType)`. Never introduce silent runtime fallback branches (`if (!$var instanceof ...) return;`) for guaranteed contracts—runtime fallbacks disguise invariants as business branches, mask upstream defects, and invite paranoid branch tests. * **Lean Operations**: Validate strictly at external boundaries; avoid defensive normalization, type-wrangling ternaries, or manual accumulator loops for internal data. Prefer idiomatic standard-library transformations (`array_filter`, `array_intersect`). ``` 2. **Fresh session (reviewing the above block against `writing-for-agents` with no prior chat context):** The model immediately flagged the text: - **Duplication:** Parent bullet and sub-bullet 2 state the exact same boundary rule twice. - **Negation:** Renders the forbidden code snippet (`if (!$var instanceof ...) return;`) directly in context, priming the banned pattern. - **Exposition:** The human-facing justification (*"—runtime fallbacks disguise invariants as business branches..."*) burns always-loaded budget without altering agent behavior. - **Rewrote to:** ```markdown * **Trust Internal Contracts**: Validate strictly at external boundaries. Past the boundary, narrow untyped payloads with `assert($var instanceof ExpectedType)`—not silent guard returns—and use native array functions (`array_filter`, `array_intersect`) directly without defensive normalization or manual loops. ``` **Why this happens:** 1. **Conversational anchoring:** When capturing discussion points, the context window is saturated with human-facing arguments, problem explanations, and prohibited anti-patterns. Single-pass generation mirrors that conversational framing into the draft. 2. **Missing verification step:** `writing-for-agents` classifies itself as pure reference (*"all reference (a review's rules, this skill)"*) and lacks an explicit completion criterion or pre-output filter (e.g. *"Audit candidate diffs: invert negated bans into positive targets, strip forbidden code samples, drop human justifications"*). 3. **Audit divergence:** Without an idempotence or completion boundary, the document behaves as pure reference during reviews, but fails to prevent conversational leakage during generation. ### Proposed change Add a short, positive pre-commit audit gate to `writing-for-agents` to govern synthesis from conversations: 1. **Pre-output audit step:** When adding or updating text from a conversation or notes, require filtering candidate wording against three specific failure modes before committing: - Strip anti-pattern code snippets (lead with the positive construct). - Invert conversational prohibitions (*"never do X"* / *"avoid Y"*) into the target behavior. - Drop the conversational rationale (*"because..."*, *"disguises..."*). 2. **Review idempotence bound:** Define when an existing line is *done* to prevent unbounded compression passes across successive review sessions when no behavioral lever is violated. **Question / Framing for feedback:** Is interactive synthesis (distilling a chat conversation into an agent document) considered an unintended off-label use case that belongs in a separate workflow/skill, or should `writing-for-agents` carry an explicit completion/audit step so that first-pass generation matches fresh-session review?