content_round3.js
// Round 3 — Editorial polish. Prompt = round2/<slug>.md + editorial mandate.
// Writes final/<slug>.md and a final/index.md. node content_round3.js [--slug s] [--limit N]
const fs = require("fs");
const path = require("path");
const { parseBriefs } = require("./lib/briefs");
const { probeModel, runRound } = require("./lib/batch");
const P = require("./lib/prompts");
const { cleanArticle } = require("./lib/clean");
const R2 = path.join(__dirname, "round2");
const OUT = path.join(__dirname, "final");
function arg(name) {
const i = process.argv.indexOf(`--${name}`);
return i >= 0 ? process.argv[i + 1] : null;
}
function readMaybe(p) {
try {
return fs.readFileSync(p, "utf8");
} catch {
return null;
}
}
async function main() {
fs.mkdirSync(OUT, { recursive: true });
const { standingRules, briefs } = parseBriefs();
let items = briefs;
if (arg("slug")) items = briefs.filter((b) => b.slug === arg("slug"));
else if (arg("limit")) items = briefs.slice(0, Number(arg("limit")));
items = items.filter((b) => {
const has = fs.existsSync(path.join(R2, `${b.slug}.md`));
if (!has) console.warn(` (skip ${b.slug}: no round2 draft)`);
return has;
});
if (!items.length) {
console.error("No round-2 drafts found. Run content_round2.js first.");
process.exit(1);
}
const model = await probeModel();
console.log(`Round 3: polishing ${items.length} post(s) with ${model}`);
const sys3 = P.round3System(standingRules);
const results = await runRound(model, items, (brief) => ({
system: sys3,
userContent: P.round3User(readMaybe(path.join(R2, `${brief.slug}.md`))),
max_tokens: 16000,
}));
let ok = 0;
const index = ["# Northern Illinois Recovery Tier A — Final Posts", ""];
for (const b of items) {
const r = results.get(b.slug);
if (r && r.ok) {
fs.writeFileSync(path.join(OUT, `${b.slug}.md`), cleanArticle(r.text));
index.push(`- [${b.workingTitle}](${b.slug}.md) — \`${b.targetKeyword}\``);
console.log(` ✓ ${b.slug} (${r.model})`);
ok++;
} else {
console.warn(` ✗ ${b.slug} — ${r ? r.error || r.stop_reason : "no result"}`);
}
}
fs.writeFileSync(path.join(OUT, "index.md"), index.join("\n") + "\n");
console.log(`\nRound 3 done: ${ok}/${items.length} final posts written to final/ (+ index.md).`);
}
main().catch((e) => {
console.error("FATAL:", e.stack || e);
process.exit(1);
});