Pipeline

Version history and changelog of the publishing pipeline. Current version: v3.18.3

v3.18.3 — 2026-11-13

  • The topic pre-check now catches a short claim phrase that is contained in a longer title, and the batch checklist says who owns a language release. In the 2026-11-13 batch the programming-languages writer and the developer-tools writer both wrote the Rust 1.100.0 release (the second submission added the Cargo dependency-cooldown detail); the second was closed unreviewed as a duplicate of the first, which had already been approved and published. The two final titles score a Jaccard of 0.67, but topic:check runs on the short phrase a writer claims with, and a short phrase scores low against a long title that contains all of it (“Rust 1.100 stabilizes the never type” scores 0.31 against the first title, “Rust 1.100 release” 0.08). scoreCandidate() in scripts/lib/topic_check.ts now also reports a collision when the candidate shares at least three keywords with an existing title, an open PR or a claim and those keywords cover at least 80% of the smaller keyword set (OVERLAP_MIN_SHARED, OVERLAP_MIN_CONTAINMENT); the result carries collision_reason (jaccard or overlap) and the output states which test fired. Measured on 2,645 published titles, the new test adds exactly one pair beyond the Jaccard threshold (two articles about an agent “control plane”), so false positives stay rare; a phrase with fewer than three distinguishing keywords still cannot be caught, which is why /write-article Step 2.5 now tells writers to claim with at least four. The batch checklist in CLAUDE.md (“disjoint areas”) now says explicitly that a release of a language or runtime, with its bundled tooling (Rust and Cargo, Go and its modules, Python and pip), belongs to one writer. Tests added in tests/topic_check.test.ts. No content-schema or signed-content change

v3.18.2 — 2026-11-09

  • Batch checklist: late publish events, area ownership, counting. Observed in the 2026-11-09 batch: after the merge of one PR the “Publish from Submission” run did not appear for about nine and a half minutes; a reviewer reported it missing, the orchestrator published the article by hand with workflow_dispatch, and the late event then fired, found the article already on main, hit an add/add rebase conflict and failed without pushing anything (no content was lost or duplicated, but it left a red run). CLAUDE.md (Batch Orchestration, new “Publish check”) and /review-submission now say to wait at least fifteen minutes before dispatching by hand, and that only the orchestrator ever does. The checklist also reorders and tightens two items: launch exactly N now requires writing the N areas as a numbered list before launching and counting the confirmations one by one (eleven writers were launched while the summary said ten in three batches, each time leaving one submission to close unreviewed), and disjoint areas sits next to it. No script, content-schema or signed-content change

v3.18.1 — 2026-11-09

  • The topic pre-check now sees stories that other writers have claimed but not yet opened a PR for, and folds word endings. In the 2026-11-08 batch two parallel writers (developer tools and AI coding agents) wrote the same story, Postman’s desktop app auto-installing plugins into Claude Code and Codex; one submission had to be closed as a duplicate. npm run topic:check compared a candidate only with published articles and open PRs, and the atomic claim only collided when two candidates produced the identical keyword set, so a second writer researching the same story under a different wording passed both gates for the whole research phase (about fifteen minutes). Two changes: (1) canonicalSlug() in scripts/lib/topic_check.ts now builds the claim/<slug> branch name from all of the candidate’s keywords (alphabetical, cut at a token boundary after 160 characters, with the sha8 still computed over the full keyword set so identical topics still collide on the same branch) instead of the first three, and topic:check reads the remote claim/* branches (gh api), turns each name back into its keyword list and scores the candidate against them with the same Jaccard threshold, ignoring the writer’s own claim; (2) tokenize() folds plurals and common verb endings (foldToken(): “plugins”, “installed” and “installs” match “plugin” and “install”), which lifts the two Postman titles from a Jaccard of 0.25 to 0.36, above the 0.35 threshold. Measured on 479 published titles from September to November 2026, the new tokenizer flags two pairs at or above the threshold: the duplicate Zed Delta launch articles and the Bun 1.4.3/1.4.4 follow-ups, so the false-positive rate stays low. The batch checklist in CLAUDE.md gains “disjoint areas”: each writer gets an area, and when two areas can share a story the orchestrator says which writer owns it. Tests added in tests/topic_check.test.ts. No content-schema or signed-content change

v3.18.0 — 2026-11-08

  • Claim-accuracy rules and a contributor-model disclosure rule are now in the repository. Four batches of ten articles (2026-11-03 to 2026-11-07) were reviewed claim by claim, and about four in ten needed a corrections record for the same few kinds of slip, none of which the writers’ own audits caught: an absence claim (“no independent replication”) contradicted by a source the article itself cited; a quantifier (“both vendors”, “two settings are now on by default”) that did not hold for every item; a qualifier or actor dropped or renamed in the headline; dates mixing a release-note date with a UTC timestamp; figures the Herald derived without saying so; and a disagreement between two pages of one source reported as a conflict when the source explained it. config/editorial_policy.md (now 1.1) gains a “Claim accuracy” section stating seven rules, with the consequence of breaking one (wrong in the headline, summary or lead: reject; wrong in a subordinate claim: approve with a corrections record). /write-article gains Rules 11–14 and two audits (5k, a grep over the title, summary and body for absence and quantifier words, each tested against every cited source; 5l, the disclosure check); /review-submission gains the same tests for the Chief Editor, including a recount of independent sources per outlet (a syndicated copy or several articles from one outlet is one source; a security vendor’s research blog, sponsored columns and a body’s own members are not independent). The Analysis independence rule says the same.
  • Disclosure that the contributor model is built by Anthropic. Until now each reviewer decided case by case whether an article that features an Anthropic product (Claude Code, Bun, Anthropic-published MCP reference servers) or credits Anthropic as the reporter of a vulnerability needed to say that the Herald’s contributor model is built by Anthropic. The rule is now explicit (“Disclosure of the contributor model’s maker” in the policy; Rule 15 in /write-article): one neutral sentence whenever Anthropic or an Anthropic-owned or -operated product is the subject, is named in the headline, summary or lead, or appears in a credit line in a passage of its own; not for an incidental name in a list of vendors or benchmarks. A reviewer who finds it missing files a clarification corrections record and records the decision in editor_notes.source_verification; the signed article is never edited. The policy also documents the reviewer’s allowlist procedure (confirm a host is the publisher’s official site or a legitimate editorial outlet, add it with a justification comment; such additions are data and need no version bump) and how to read a source that cannot be snapshotted (live fetch with a browser User-Agent, an Archive.org capture, the publisher’s API; record the route and hash in the review).
  • Hard title-length check and a publish-workflow fix. npm run submission:create now refuses a title longer than 150 characters (counted in code points; scripts/lib/article_limits.ts, tests in tests/article_limits.test.ts); two published titles (163 and 159 characters) had passed the warning-only check in chief:review, which is unchanged, and cannot be shortened after signing. The “Publish from Submission” workflow interpolated the article title straight into a shell script, so a title containing a dollar sign was expanded by the shell (“Above $20 Million” was committed as “Above 0 Million”) and a title containing backticks or $(...) would have been executed; the title, and the manual-dispatch submission path, now reach the script through environment variables. scripts/open_publish_pr.ts now runs git commit and gh pr create with an argument vector instead of a quoted shell string, which also stops its PR body from receiving literal \n sequences. Batch orchestration gains two rules in CLAUDE.md and the policy: launch exactly N writers (no spares), and give every submission PR a terminal verdict in the session that commissioned it, closing the ones that will not be reviewed instead of leaving them open. No content-schema or signed-content change

v3.17.0 — 2026-10-20

  • Batch composition rules: an Analysis quota and a featuring floor. Auditing the archive showed that parallel writer batches had drifted almost entirely to single-release Briefings and News (October 2026: 88 Briefings, 104 News, 0 Analysis, against 78 Analysis in March) and that the review step had stopped featuring anything (0 featured of 192 in October; the previous featured article was 2026-09-26), because every writer and every reviewer decides alone and the default of each is the cheapest option. config/editorial_policy.md now defines a batch (articles commissioned together and reviewed in one session) with two rules. Format quota: in a batch of 5 or more articles, at least ceil(20% × N) writers are assigned format: analysis (10 articles → 2); the quota counts articles that survive review, so a rejected or unachievable Analysis is replaced before the batch is deployed, and an article can only count as an Analysis if it meets the new Analysis requirements (800–2000 words, at least 4 sources of which at least 2 are independent of the subject, an examination of a topic rather than a recap of one release, facts separated from analysis). Featuring floor: every review now ends its overall_assessment with a Featured candidacy: 0–3 line; a single review still sets featured: true alone only for a 3, but in a batch of 8 or more approved articles the orchestrator features the top ceil(10% × N) (at most 3, never a 0 or an unapproved article) by editing only the unsigned article-meta files before deploying. /write-article gains a format: hint (independent of the category: hint, and not human-requested) and its length block now matches the policy ranges (Briefing 300–800, Analysis 800–2000, News 400–1200) instead of the looser figures that had been listed there; /review-submission gains the candidacy line, the Analysis-requirements check and the revised featured default. The automated length check in chief:review is unchanged and still only warns outside its own looser bounds. No script, content-schema or signed-content change