Add librarian Stage 2 v1: promote dispatcher

scripts/librarian_promote.py is the first Stage 2 piece: a
vendor-agnostic LLM dispatcher that drafts a docs/research/ note
from a given docs/archive/ entry. It assembles the prompt by
stitching scripts/librarian-prompt.md (system) onto the archive
body with a "draft a research note per the rules above" task
instruction, then shells out to the CLI selected by LIBRARIAN_LLM
({claude|codex|gemini}; default claude). The LLM's stdout is
captured to runs/tmp/librarian-promote-<timestamp>-draft.md for
human review — the script never writes into docs/research/ itself.

Refusal cases:
- path not under docs/archive/
- target docs/research/<stem>.md already exists (after stripping any
  -YYYY-MM-DD suffix)
- archive missing

If the LLM judges the archive non-promotable, it is instructed to
return a single SKIP: <reason> line instead of fabricating a draft.

--show-prompt prints the assembled prompt without invoking the LLM,
useful for inspecting what would be sent.

Plan updated: Stage 2 v1 marked complete; remaining Stage 2 work
(MEMORY drift fixup, duplicate-merge, survey mode) catalogued.
Next concrete step is a smoke test against one real archive entry.

Adds one ignore-list entry for docs/research/option-a-bench-result.md
which appears in the plan as a hypothetical accept target.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-08 00:05:38 +09:00
co-authored by Claude Opus 4.7
parent 1cd9950bd3
commit 8bbed31670
3 changed files with 208 additions and 6 deletions
+35 -6
View File
@@ -183,11 +183,40 @@ routing the dated experiments and design analysis out of the file:
extracts via a "See Also" section. AGENTS.md soft-cap rule reworded
to clarify it is a *routing trigger*, not a split mandate.
## Stage 2 v1: promote dispatcher
`scripts/librarian_promote.py`. Takes a `docs/archive/*.md` path,
stitches `scripts/librarian-prompt.md` (system prompt) onto the
archive body with a "draft a research note" task instruction, then
shells out to the LLM CLI selected by `LIBRARIAN_LLM`
(claude / codex / gemini; default claude). Output is captured to
`runs/tmp/librarian-promote-<timestamp>-draft.md` for human review;
the script never writes into `docs/research/` itself. `--show-prompt`
prints the assembled prompt for inspection without calling the LLM.
Refuses to run if:
- the path is not under `docs/archive/`,
- the implied target `docs/research/<stem>.md` already exists, or
- the file is missing.
If the LLM judges the archive non-promotable, it is instructed to
return a single line `SKIP: <reason>` instead of a draft.
## Stage 2 remaining
- MEMORY.md drift fixup mode (read drift report, propose one-line
diffs).
- Duplicate-doc merge proposal mode.
- Survey mode: scan all archive entries lacking a research
counterpart and run `librarian_promote` on each, accumulating
drafts under one timestamped directory.
## Next Concrete Step
Stage 2 — LLM judgment dispatcher. Read `librarian-<timestamp>.json`
+ relevant doc bodies, route to `LIBRARIAN_LLM={claude|codex|gemini}`
with `scripts/librarian-prompt.md` as system prompt, emit a unified
diff under `runs/tmp/librarian-<timestamp>.patch`. Initial use cases:
research-note drafts for promotable archive entries, MEMORY.md drift
fixups, duplicate-doc merge proposals.
Smoke-test `librarian_promote.py` against one real archive entry
(`docs/archive/option-a-bench-result-2026-05-07.md` is a good
candidate — durable architecture content). Run with the default
claude backend, review the draft, and either accept it as
`docs/research/option-a-bench-result.md` or note specific
edit-distance from what we'd want. The result drives whether the
prompt template needs tightening before adding survey mode.