Skip to content

Batch/Librarian write path drops per-topic confidence from note frontmatter #12

Description

@TimSimpsonJr

Summary

Notes written through the batch fan-out path (Stage 3.5 → Stage 4B → research-batch.js → Librarian write) do not carry the confidence: frontmatter field, while notes written through the inline path (SKILL Stage 7c.v, orchestrator-written) do. This makes a large batch run's notes inconsistent with single-topic runs.

Observed on v3.2.0: a 9-topic batch produced 19 notes with research_run but no confidence; an inline run of the same depth stamps confidence: <topic.confidence_history[-1]>.

Root cause

confidence is a research-side value (topic.confidence_history). The batch write span is summaries → classify → librarian-write, and the number is dropped at the first hop:

  • collectSummaries(topics) (.claude/workflows/research-batch.js ~L573) flattens each topic's per-source summary items into {topic, ...item}. It does not attach the topic's final confidence, so the score never leaves the topic object.
  • The librarian:classify-agent receives only those summaries and emits notes_to_create[] with a generic frontmatter_meta built from tags/type (CLASSIFY schema, ~L197). It has no confidence value to place there.
  • writerAgent(...) is passed low_confidence (the list of failing topic names, ~L412) but no per-note numeric confidence, and its prompt doesn't ask for one. Librarian writes the neutral contract faithfully; confidence isn't in it.

Librarian already supports this as pass-through — agents/classify-agent.md:247 states frontmatter_meta may carry "any caller metadata (e.g. created, confidence)" — but nothing in the researcher handoff populates it. (scripts/taxonomy.py:66 frontmatter_fields = [title, tags, source, created] is only the completeness-lint set, not a cap.)

The low_confidence array only drives a body callout for failing topics; when all topics pass the gate it's empty, so passing notes get neither a callout nor a numeric field.

Impact

  • Batch-written notes are missing confidence, inconsistent with inline-written notes and with any downstream tooling that reads the field.
  • No per-note confidence signal survives on the highest-throughput path (the one used for large runs).

Suggested fix (code-only)

Thread each topic's final confidence into the write span, then inject it into frontmatter_meta.confidence (Librarian writes it as-is):

  1. In research-batch.js, carry a topic → confidence map (last confidence_history value per topic) into runWrite. Options:
    • tag each item in collectSummaries with its topic's confidence, and have the classify handoff / writer copy it into frontmatter_meta.confidence; or
    • simplest: in runWrite, after classify returns notes_to_create, post-stamp each note's frontmatter_meta.confidence from the topic map before calling writerAgent (map note→topic by citation/source overlap).
  2. Keep parity with inline Stage 7c.v (single-hop → 1.0; else last confidence_history).

Repro

Run a batch that routes through Stage 4B and compare written-note frontmatter to a single-topic inline run of the same depth: batch notes lack confidence:, inline notes have it.

Workaround used

Post-run, recomputed per-topic confidence from the classify-input summaries (the inlined computeConfidence formula) and stamped the batch notes manually.


Filed from a DeflockSC research session (2026-07-02). Code-only follow-up — labeled autonomous-safe.

Metadata

Metadata

Assignees

No one assigned

    Labels

    autonomous-safeCode-only follow-up; eligible for autonomous pickup

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions