# auto-draft ## Purpose Scan the writing dossiers for AI-pipeline work and schedule jobs in priority order, using only the "spare" capacity of the current subscription window. Designed to be run from a cron job (hourly) so that it picks up work as spare capacity appears. The script is **dryrun-only** in this revision: it shows the spare capacity and the three priority queues, but does not execute any jobs. Job execution is a later stage. ## Usage ``` auto-draft --provider --threshold --polish-score <0-10> [OPTIONS] Required: --provider PROVIDER Subscription provider to draw capacity from: anthropic or minimax --threshold PERCENT Maximum subscription utilisation allowed over the period, as a percentage (e.g. 50 = use up to 50% of the weekly allowance). The script computes the linear limit at the current point in the period and reports the spare capacity. --polish-score N Paragraph score below which a paragraph is queued for polishing (e.g. 7 means "polish any paragraph with score < 7"). Options: --base-dir PATH Root directory to scan for dossier files. Defaults to ".". Recurses into subdirectories. -n, --dryrun Show capacity and queues without executing. This is the default behaviour for this revision; the flag is explicit so the cron command line is self-documenting. -h, --help Show this help message and exit. ``` ## Behaviour 1. Probe the live subscription for the given provider. The script shells out to `agent-subscriptions --output json` and reads the relevant provider's `seven_day` window. 2. Compute the spare capacity against the supplied threshold: - `last_renewed = reset_at - 7 days` (the weekly window is treated as a rolling 7-day period) - `period_seconds = 7 * 86400` - `elapsed_seconds = max(0, now - last_renewed)` - `limit_pct = elapsed_seconds / period_seconds * threshold` (the linear allowance at this point in the period) - `spare_pct = limit_pct - utilization_pct` (positive = under budget, negative = over budget) 3. Discover titles by scanning for `*.overview.md` source files under `--base-dir` (recursively). Each title is the stem of the source file (e.g. `01-ai-is-an-amplifier`); the numeric ID is the leading digits before the first `-`. 4. Build three priority queues, in priority order: - **Polish queue (highest priority)** — for every title whose `*.ai_score..md` exists, parse the file and find paragraphs with `score < polish_score` and not marked exempt. If any such paragraph exists, the whole title is queued for polish. - **Scoring queue (second priority)** — for every title whose `*.ai_generated..md` exists but whose `*.ai_score..md` does not. The job is to score the generated file. - **Generation queue (lowest priority)** — for every title whose `*.ai_generated..md` does not exist. The job is to generate the draft from the source brief. 5. Sort each queue by numeric ID ascending (titles without a numeric ID sort last). 6. Print the spare capacity and the three sorted queues. ## Score file format The `*.ai_score..md` files embed per-paragraph scores and an exempt marker as inline HTML comments after each paragraph: ```markdown This is a great paragraph with polish. This is a middling paragraph. This is already reviewed and acceptable. ``` Regex patterns: - Score: `` - Exempt: `` A paragraph is queued for polish if it has a score comment with a value below `polish-score` AND does not have an exempt comment. Paragraphs without a score comment are not eligible for polishing (they are skipped), even if the file contains other scored paragraphs. ## Spare capacity output ``` [auto-draft] Spare capacity for Anthropic Reset at: 2026-08-07T23:00:00+00:00 Renewed at: 2026-07-31T23:00:00+00:00 Elapsed: 16h 18m of 7d (9.7%) Threshold: 50.0% Linear limit: 4.9% Current usage: 41.2% Spare capacity: -36.4% (over budget; do not queue any work) ``` For a healthy budget: ``` Spare capacity: 23.5% (under budget) ``` ## Queue output ``` [auto-draft] Polish queue (priority 1) — 3 items 01-ai-is-an-amplifier 2 paragraphs below 7 (of 4 scored) 02-five-layers-of-an-agent-harness 1 paragraph below 7 05-the-compound-engineering-loop 3 paragraphs below 7 [auto-draft] Scoring queue (priority 2) — 1 item 03-shadow-agents-are-the-new-shadow-it [auto-draft] Generation queue (priority 3) — 8 items 04-risk-proportionate-delivery 06-backpressure-is-coming-for-your-ci 07-tests-are-law-llms-are-not-the-judge ... ``` ## Edge cases - If the provider probe fails (`available: false`), print a warning and skip the capacity section. Still build and print the queues. - If the seven-day `reset_at` is missing, skip the capacity section (cannot compute `last_renewed`). Still build and print the queues. - If a title has no numeric ID prefix, sort it last in every queue. - If the base directory contains no source files, print all three queues as empty. - If a source file's directory also contains the `ai_score` and `ai_generated` files, the title is in the polish queue (or none, if all paragraphs pass). Otherwise scoring or generation. - Exit 0 unless the CLI args are invalid. The script is informational; one bad provider probe should not fail the cron. ## Dryrun behaviour This revision is dryrun-only. The script always prints the capacity and queues. Job execution is out of scope until the design is approved. ## Examples ```sh auto-draft --provider anthropic --threshold 50 --polish-score 7 auto-draft --provider anthropic --threshold 50 --polish-score 7 --base-dir /home/paul/dev/claude/writing/oreillyconsulting auto-draft --provider minimax --threshold 70 --polish-score 8 --dryrun ```