idle-draft: idle-subscription dispatcher for the writing pipeline
Elapsed-paced gates, bounded-parallel event-driven dispatch, filesystem- derived stages with thin human-gate state, citation validation with quarantine, credential parity check, prompt templates as data. Per IDLE-DRAFT-PLAN.md in writing/oreillyconsulting. Claude-Session: https://claude.ai/code/session_01YQDoWNM7XPPii28khFWoMc
This commit is contained in:
24
data/idle-draft/config.example.json
Normal file
24
data/idle-draft/config.example.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"parallel": 2,
|
||||
"providers": {
|
||||
"anthropic": { "profile": "~/.claude-oreillyit-anthropic", "threshold_pct": 80,
|
||||
"five_hour_ceiling": 50, "min_idle": 5 },
|
||||
"minimax": { "profile": "~/.claude-oreillyit-minimax", "threshold_pct": 80,
|
||||
"five_hour_ceiling": 50, "min_idle": 5 }
|
||||
},
|
||||
"work_types": {
|
||||
"review": { "providers": ["anthropic"] },
|
||||
"draft": { "providers": ["anthropic"] },
|
||||
"research": { "providers": ["anthropic", "minimax"] },
|
||||
"topic_ideas": { "providers": ["anthropic", "minimax"] }
|
||||
},
|
||||
"dossiers": ["ai", "ai-technical", "devops-2020", "devops-2020-technical"],
|
||||
"review_score_threshold": 11,
|
||||
"max_unreviewed_research_per_dossier": 3,
|
||||
"max_open_topic_proposals": 6,
|
||||
"evidence_dirs": [
|
||||
"~/dev/claude/octopus/goes",
|
||||
"~/dev/claude/projects/agent-runtimes",
|
||||
"~/dev/claude/projects/agent-runtimes-work-items"
|
||||
]
|
||||
}
|
||||
55
data/idle-draft/prompts/draft.md
Normal file
55
data/idle-draft/prompts/draft.md
Normal file
@@ -0,0 +1,55 @@
|
||||
You are producing the **published-track draft article** for one topic in an O'Reilly
|
||||
Consulting writing dossier. This is unattended, headless work — a human edits this
|
||||
draft before it moves further, but there is no human in the loop while you write it.
|
||||
Follow this brief exactly; do not invent structure.
|
||||
|
||||
## Item
|
||||
|
||||
- Dossier: `$dossier`
|
||||
- Topic: `$slug`
|
||||
- Topic brief: $overview_path
|
||||
- Commissioning brief — **this is the contract for the article; follow its required
|
||||
structure exactly**: $agent_path
|
||||
- Research file — your evidence source, already validated: $research_path
|
||||
- Dossier commissioning guide: $dossier_agents_path
|
||||
- Project-root voice, style, and citation rules — read before writing a single line:
|
||||
$agents_root_path
|
||||
- Voice reference (read this one in full; it is the canonical synthesis): $style_dir/goes-target-voice.md
|
||||
|
||||
## What to produce
|
||||
|
||||
Follow the commissioning brief's required structure exactly — it is the contract, not
|
||||
a suggestion. Do not add sections it doesn't name; do not omit sections it does.
|
||||
|
||||
## Voice rules (non-negotiable)
|
||||
|
||||
- **Sentence-case headings** everywhere: "The decision," not "The Decision."
|
||||
- **Consulting dossiers** (`ai`, `devops-2020`): open with a judgment the reader would
|
||||
pay for, not a category they already know. **Do not name vendors in prose.** If a
|
||||
source credits a specific vendor or product, say "the platform team" or "their
|
||||
engineering organisation" instead — vendor names stay in the source register and the
|
||||
commissioning brief, never in the published copy.
|
||||
- **Technical dossiers** (`ai-technical`, `devops-2020-technical`): open with the
|
||||
specific toil the reader lives with, not the category a vendor markets. Naming a
|
||||
specific tool, script, or system by its actual identifier is fine here — this is
|
||||
implementation detail, not vendor marketing.
|
||||
- **Cite the file, not the concept**, for any code or spec reference (path + line
|
||||
range). **Make a claim, cite the case, name the source**, for any research finding.
|
||||
Use the dossier's correct status-label family (see `$agents_root_path`) on every
|
||||
cited claim.
|
||||
- **Distinguish research from implementation.** Do not conflate "the research finds X"
|
||||
with "the implementation does Y." The research is the question; the implementation
|
||||
is one possible answer; state the connection explicitly.
|
||||
- No hedge words where the evidence supports a direct claim. No marketing language. No
|
||||
AI tells (see the burn list in `$style_dir/tone-and-voice.md` if you are unsure what
|
||||
that means).
|
||||
|
||||
## Output
|
||||
|
||||
Write the complete Markdown article to exactly this path, and nothing else:
|
||||
|
||||
$output_path
|
||||
|
||||
The dispatcher validates this file (non-empty, starts with a top-level heading) and
|
||||
promotes it to its canonical location itself. A human edits this draft next — write it
|
||||
as if a careful editor, not a lenient one, will read it in the next hour.
|
||||
89
data/idle-draft/prompts/research.md
Normal file
89
data/idle-draft/prompts/research.md
Normal file
@@ -0,0 +1,89 @@
|
||||
You are producing the **research file** for one topic in an O'Reilly Consulting
|
||||
writing dossier. This is unattended, headless work — there is no human in the loop
|
||||
until a reviewer samples your output later. Follow this brief exactly.
|
||||
|
||||
## Item
|
||||
|
||||
- Dossier: `$dossier`
|
||||
- Topic: `$slug`
|
||||
- Topic brief (read first, in full): $overview_path
|
||||
- Commissioning brief (read second, in full): $agent_path
|
||||
- Dossier commissioning guide (dossier-specific rules): $dossier_agents_path
|
||||
- Project-root voice and citation rules (read before writing a single line): $agents_root_path
|
||||
- Source register (existing sources for this dossier — read before searching for new
|
||||
ones; do not duplicate a source it already lists): $source_register_path
|
||||
|
||||
Evidence you may cite must live under one of these directories (you have read access
|
||||
via `--add-dir`; do not invent paths outside them):
|
||||
|
||||
$evidence_dirs
|
||||
|
||||
## What to produce
|
||||
|
||||
Write a Markdown research file with two kinds of content, matching what the topic
|
||||
brief's evidence section and the commissioning brief already point at, extended with
|
||||
anything new and relevant you find under the evidence directories above:
|
||||
|
||||
1. **Objective evidence** — concrete examples, code references (file path + line range,
|
||||
not just "the script does X"), measurables, named findings. Every claim is sourced.
|
||||
2. **Subjective stories** — case-study-like narratives that make the evidence concrete
|
||||
for a reader (a scene, a named organisation's experience, a practitioner's account)
|
||||
— still sourced, but framed as narrative rather than a bare statistic.
|
||||
|
||||
## Citation rules (non-negotiable — read `$agents_root_path` for the full statement)
|
||||
|
||||
- **Cite the file, not the concept.** Any code or spec reference must name the file
|
||||
path and the line range: `path/to/file.py:120-145`, not "the script does X."
|
||||
- **Cite the requirement ID where one exists** (e.g. `H-*`, `AU-*`, `WT-*`, `KX-*`,
|
||||
`BRK-*`, `WF-*` prefixes in the agent-runtimes spec) — quote the ID, not a prose
|
||||
paraphrase.
|
||||
- **Quote metric markers verbatim** where GOES research uses them (`{p.3}`, `{s.4}`,
|
||||
`{t.00:14:32}`) — do not renumber or invent markers.
|
||||
- Use the dossier's status-label family and apply it correctly:
|
||||
- `ai` / `ai-technical` dossiers use **implementation maturity**: "Implemented and
|
||||
running in production" / "Designed and specified, implementation in progress" /
|
||||
"Spec-only / future." A claim about an `implemented` feature may report a deployed
|
||||
behaviour or measured metric; a `spec-only` claim may not.
|
||||
- `devops-2020` / `devops-2020-technical` dossiers use **evidence quality**: "Named
|
||||
organisation, self-reported" / "Research-survey finding" / "GOES synthesis / bet" /
|
||||
"Vendor data, treat with caution." Label every cited source with the correct one.
|
||||
- Every source you cite gets an explicit status label. Do not present an unlabelled
|
||||
claim as settled fact.
|
||||
|
||||
## Required structure
|
||||
|
||||
```markdown
|
||||
# Research: <topic title, sentence case>
|
||||
|
||||
## Objective evidence
|
||||
|
||||
<bulleted or short-paragraph entries, each with file/line or source citation and
|
||||
status label>
|
||||
|
||||
## Subjective stories
|
||||
|
||||
<narrative entries, each still sourced and status-labelled>
|
||||
|
||||
## Register delta
|
||||
|
||||
<a bulleted list of every source used in this file that `$source_register_path` does
|
||||
NOT already list — path, one-line description, proposed status label. If every source
|
||||
you used is already in the register, write "None — all sources already registered."
|
||||
This section is the only place new sources are proposed; you do not edit the register
|
||||
file itself.>
|
||||
```
|
||||
|
||||
All headings are **sentence case** ("Objective evidence," not "Objective Evidence").
|
||||
|
||||
## Output
|
||||
|
||||
Write the complete Markdown file to exactly this path, and nothing else — do not touch
|
||||
any other file in the repository, do not edit the source register, do not create the
|
||||
canonical `$slug.research.md` file yourself:
|
||||
|
||||
$output_path
|
||||
|
||||
The dispatcher validates this file (non-empty, starts with a top-level heading, every
|
||||
absolute `/home/...` path you cite resolves on disk) and promotes it to its canonical
|
||||
location itself. If any cited absolute path does not exist, your output will be
|
||||
rejected — verify paths before citing them, don't guess.
|
||||
62
data/idle-draft/prompts/review-suggest.md
Normal file
62
data/idle-draft/prompts/review-suggest.md
Normal file
@@ -0,0 +1,62 @@
|
||||
You are producing the **review file** for one human-edited draft in an O'Reilly
|
||||
Consulting writing dossier. The draft has already been scored per-paragraph on the
|
||||
5-dimension `/15` rubric (Evidence, Judgment, Voice, Rhythm, Register — see
|
||||
`score-paragraphs`); your job is the **second pass**: concrete, actionable improvement
|
||||
suggestions for every paragraph that scored below the threshold.
|
||||
|
||||
## Item
|
||||
|
||||
- Dossier: `$dossier`
|
||||
- Topic: `$slug`
|
||||
- Human-edited draft (already scored, score blocks inline): $draft_path
|
||||
- Grading template — apply the same rubric and voice bar when suggesting fixes:
|
||||
$review_prompt_path
|
||||
- Voice reference: $style_dir/goes-target-voice.md
|
||||
- Score threshold on the `/15` scale: **$review_score_threshold** — any paragraph
|
||||
scoring below this needs a suggestion; paragraphs at or above it need none.
|
||||
|
||||
## What to produce
|
||||
|
||||
For every paragraph in the draft whose inline score block shows a total below
|
||||
`$review_score_threshold`:
|
||||
|
||||
- Quote the paragraph's opening few words so a human can locate it.
|
||||
- Name which of the five dimensions is weakest and why, in one sentence.
|
||||
- Give a **concrete rewrite direction** — not "improve the evidence," but what
|
||||
specific evidence, source, or file/line citation would raise the score, or what
|
||||
specific sentence-level change (cut a hedge word, vary sentence length, cut a
|
||||
vendor name, cite the file instead of the concept) would fix it.
|
||||
|
||||
Do not rewrite the paragraph yourself — suggest, don't replace. The human author makes
|
||||
the edit.
|
||||
|
||||
## Required structure
|
||||
|
||||
```markdown
|
||||
# Review: <topic title, sentence case>
|
||||
|
||||
## Summary
|
||||
|
||||
<one paragraph: how many paragraphs scored below threshold, out of how many total,
|
||||
and the single most common weak dimension>
|
||||
|
||||
## Suggestions
|
||||
|
||||
### Paragraph opening: "<first few words...>"
|
||||
|
||||
- Score: <total>/15 (weakest dimension: <name>)
|
||||
- Suggestion: <concrete, specific>
|
||||
|
||||
<repeat per below-threshold paragraph, in document order>
|
||||
```
|
||||
|
||||
All headings are **sentence case**.
|
||||
|
||||
## Output
|
||||
|
||||
Write the complete Markdown file to exactly this path, and nothing else:
|
||||
|
||||
$output_path
|
||||
|
||||
The dispatcher validates this file (non-empty, starts with a top-level heading) and
|
||||
promotes it to its canonical location itself.
|
||||
67
data/idle-draft/prompts/topic-ideas.md
Normal file
67
data/idle-draft/prompts/topic-ideas.md
Normal file
@@ -0,0 +1,67 @@
|
||||
You are proposing **new candidate topics** for one dossier in the O'Reilly Consulting
|
||||
writing pipeline. This runs only when no other work is currently eligible — the
|
||||
dossier's existing topics are all blocked on a human step or already have enough work
|
||||
in flight. Do not invent structure; follow this brief.
|
||||
|
||||
## Dossier
|
||||
|
||||
- Dossier: `$dossier`
|
||||
- Dossier commissioning guide: $dossier_agents_path
|
||||
- Project-root voice and citation rules: $agents_root_path
|
||||
- Voice reference: $style_dir/goes-target-voice.md
|
||||
|
||||
Evidence you may cite must live under one of these directories (you have read access
|
||||
via `--add-dir`):
|
||||
|
||||
$evidence_dirs
|
||||
|
||||
## Do not duplicate an existing topic
|
||||
|
||||
These titles already exist as numbered topic briefs or open proposals in this dossier.
|
||||
Do **not** propose anything that duplicates or trivially rephrases one of these:
|
||||
|
||||
$existing_titles
|
||||
|
||||
## What to produce
|
||||
|
||||
Propose **up to $max_new** new candidate topics for this dossier, each grounded in
|
||||
something you actually found under the evidence directories above — not a generic
|
||||
industry-trend guess. For each candidate:
|
||||
|
||||
- A working title (sentence case, matching the dossier's existing topic-title style).
|
||||
- A one-paragraph pitch: the decision or toil the topic would address, matching the
|
||||
audience of this dossier (CTO/VP for consulting dossiers, implementing engineers for
|
||||
technical dossiers — see `$dossier_agents_path` for which this is).
|
||||
- 2–4 evidence pointers: file paths under the evidence directories, with a one-line
|
||||
note on what each contains. Use the dossier's correct status-label family (see
|
||||
`$agents_root_path`) on each.
|
||||
|
||||
You are proposing, not commissioning: **never create a numbered `NN-slug` file.** A
|
||||
human promotes a proposal to a numbered brief later.
|
||||
|
||||
## Required structure (append this, do not replace the file)
|
||||
|
||||
```markdown
|
||||
## <Working title, sentence case>
|
||||
|
||||
**Pitch:** <one paragraph>
|
||||
|
||||
**Evidence:**
|
||||
|
||||
- <path> — <one-line note, status label>
|
||||
- <path> — <one-line note, status label>
|
||||
```
|
||||
|
||||
One `##` block per proposed topic. All headings sentence case. No vendor names in
|
||||
prose for consulting dossiers (`ai`, `devops-2020`) — vendor names may stay in the
|
||||
evidence pointers' one-line notes only.
|
||||
|
||||
## Output
|
||||
|
||||
Write **only the new `##` blocks** (not the whole file — this content will be appended
|
||||
to the dossier's existing `TOPIC-PROPOSALS.md`) to exactly this path:
|
||||
|
||||
$output_path
|
||||
|
||||
The dispatcher validates this file (non-empty, starts with a top-level `##` heading)
|
||||
and appends it to the canonical proposals file itself.
|
||||
Reference in New Issue
Block a user