06-reference

process newsletter i12 fix proposal

2026-06-29·reference·source: internal-review·by Ray (COO agent)
process-newsletterauditi12skill-improvementdeterministic-validation

/improve Proposal: Deterministic I12 Heading Validation in the Process-Newsletter WATCH Path

Status: Awaiting founder greenlight
Notion task: https://app.notion.com/p/38ef7d4936d181cb9ebaf86d75676a64
Source: Review 16 (2026-06-28) + /improve autonomous run 2026-06-29


Problem statement

The watch-mode subagent (Mode 4) keeps emitting curation/hybrid notes whose body section uses an invented heading synonym instead of the two canonical headings that the I12 audit invariant requires:

Examples from Review 16 (2026-06-28):

Recurrence history (5+ cycles):

Why wording fixes don't converge: The subagent, under instruction load, substitutes a semantically reasonable synonym (## Stories covered, ## Main Essay, ## Digest Items) that no enumerated list anticipated. The space of plausible synonyms is unbounded. Two prior /improve wording fixes prove the approach doesn't converge. The durable fix must be deterministic and mechanical — run the audit script as a gate, not post-hoc.


Why this is in the vault

Documents the structural /improve proposal for wiring audit-newsletter-outputs.py I12 check into the watch loop's write path. Preserves the rationale for Option A (pre-write gate) vs alternatives, and serves as the greenlight artifact for the SKILL.md edit.


Proposed fix: Option A — Pre-write I12 gate in the watch orchestrator

Mechanism

After each subagent writes its vault note and returns its one-line summary, the watch parent orchestrator runs a targeted I12 check on that specific file before proceeding to the next. If I12 fails, the orchestrator re-dispatches the subagent with the specific failure message to rewrite the note — not a general re-process, just a targeted heading correction.

This wires audit-newsletter-outputs.py (which already computes I12 correctly and deterministically) into the write-time path rather than the days-later post-hoc review path.

Why this is the right level

Implementation detail

The audit script already supports --strict (exits 1 on any violation) and --since (restricts to a date window). The parent can call it scoped to the single new file using --since <file-date> or by passing a single-file check variant.

Simpler approach: Rather than calling the full audit script with --since, the parent can inline the I12 check directly (read the written file, check if newsletter_format is curation or hybrid, verify the heading pattern exists). This avoids the 7-day window ambiguity and makes the check surgical.


SKILL.md diff — proposed change to Mode 4

The change is to Step 3 of Mode 4 (the watch orchestrator loop), adding a post-write I12 gate between "subagent returns" and "parent collects summary lines."

Current text (lines 96–110 of SKILL.md, Mode 4 Step 3 and Step 4)

3. **Spawn one subagent per remaining message** (max 3 concurrent) using the Agent tool with `subagent_type: general-purpose`. Each subagent:
   - Receives the message ID and the sender slug
   - Follows the **"Process one message"** steps 1-6 for exactly that ID — including the full body fetch, classification, sponsor detection, optional link follows, and writing the vault note
   - **MUST satisfy this canonical-schema pre-write checklist before writing the vault note** (added 2026-05-08 ...)
     [... full checklist ...]
   - Returns ONLY a one-line summary: `<filename> | <format> | <mapping-strength: strong/medium/weak/skip> | <one-sentence why>`

   **Subagent-depth fallback:** [...]
4. **Parent collects summary lines.** The full message bodies never enter parent context. Even at 4-8 messages per watch run that's 30-100KB saved per cycle.
5. **Report**: aggregate the summaries, flag any tracked-author candidates or new sponsor patterns surfaced.

Proposed replacement (insert new Step 3b between Step 3 and Step 4)

3. **Spawn one subagent per remaining message** (max 3 concurrent) using the Agent tool with `subagent_type: general-purpose`. Each subagent:
   - Receives the message ID and the sender slug
   - Follows the **"Process one message"** steps 1-6 for exactly that ID — including the full body fetch, classification, sponsor detection, optional link follows, and writing the vault note
   - **MUST satisfy this canonical-schema pre-write checklist before writing the vault note** (added 2026-05-08 ...)
     [... full checklist unchanged ...]
   - Returns ONLY a one-line summary: `<filename> | <format> | <mapping-strength: strong/medium/weak/skip> | <one-sentence why>`

   **Subagent-depth fallback:** [...]

**3b. I12 gate — parent validates each written note before collecting its summary.**

After each subagent returns, the parent orchestrator runs a deterministic I12 check on the written file. This runs the audit script scoped to only that file:

```bash
~/.claude/scripts/graph-db-venv/bin/python3 \
  ~/.claude/scripts/audit-newsletter-outputs.py \
  --since <file-date> --strict --json

Or inline (faster, no date-window ambiguity): read the written file, check frontmatter newsletter_format, if curation or hybrid then verify that the body contains ## Curation section or ## Issue contents (case-insensitive level-2 markdown heading).

If I12 passes: collect the subagent's summary line and continue.

If I12 fails: re-dispatch the same subagent with a targeted correction prompt:

"The note at <filepath> was just written but fails the I12 structural invariant: newsletter_format is <curation|hybrid> but the body has no ## Curation section or ## Issue contents heading. Rename the existing curation/digest/stories section heading to exactly ## Curation section (or ## Issue contents if the note enumerates issue items). Do not rewrite the content — only fix the heading. Return the same one-line summary once the heading is corrected."

This is a surgical heading rename, not a full reprocess. The re-dispatch should take < 1 turn for the subagent.

Cap: max 1 re-dispatch per note. If I12 still fails after the re-dispatch, log the failure and continue (parent includes I12-FAIL in the summary line so the report surfaces it). Do NOT loop.

  1. Parent collects summary lines (after I12 gate passes or 1-retry exhausted). The full message bodies never enter parent context.
  2. Report: aggregate the summaries. Any I12-FAIL lines become a "DECISION NEEDED" item since they represent a note that may need manual repair.

---

## Why not the alternatives

**Option B — Write a `06-reference/` filesystem hook:** A pre-commit or inotify hook that runs the audit before any file write. Pros: catches ALL write paths (not just watch mode). Cons: requires OS-level hook infrastructure, more complex to install/maintain, not portable across Claude Code sessions. Given the recurrence is concentrated in watch mode, Option A is the right minimum viable gate.

**Option C — Patch the subagent prompt a third time:** Already tried twice (2026-05-08, 2026-06-24). Wording enumeration against an unbounded synonym space does not converge. The improve/SKILL.md Recurrence Guardrail (step 2b, added 2026-06-29) explicitly disallows a third wording fix for this pattern.

**Option D — Run audit post-write but before reporting (current Step 8):** Already exists (Mode 4 Step 8 runs the full audit post-hoc). The problem is Step 8 is informational — it surfaces failures without blocking or auto-fixing. The gap is the absence of a write-time gate with auto-correct. Option A adds the gate at the right moment.

---

## Acceptance criterion

A fresh watch-mode curation/hybrid note passes `audit-newsletter-outputs.py --strict` I12 on first write (or after the one automatic re-dispatch), with zero `/self-review --fix` I12 repairs needed over a 2-week observation window (2 Review cycles).

---

## Mapping against Ray Data Co

This is a RDCO operations harness improvement. The `process-newsletter` skill is a core ingestion pipeline; I12 failures degrade vault quality and require manual repair in self-review. Fixing the gate moves RDCO from a reactive-repair loop to a write-time prevention pattern — consistent with the `audit-newsletter-outputs.py` philosophy ("zero LLM calls, cannot hallucinate a pass").

The parent-gate pattern also generalizes: any invariant that is cheap to check deterministically should run at write time, not 7 days later in self-review. This proposal pilots that pattern for I12; future `/improve` runs can extend it to I8/I9 if heading drift ever appears there.

---

## Related

- [[2026-04-19-newsletter-output-invariants]] — full I1-I13 spec
- [[2026-06-24-improve-process-newsletter-run]] — the last `/improve` run that added the 2nd wording fix (now superseded by this proposal)
- [[2026-04-11-garry-tan-thin-harness-fat-skills]] — source framework for thin harness, fat skills / skill self-improvement loop