OSS Knowledge Base · Docs

Weekly digest

Every day the Dev environment turns the last seven days of Kafka activity into a short bilingual summary: topic cards, KIP proposals by stage, and a headline, each sentence citing the records it is based on. Language models write the text; deterministic rules decide what may be published.

The pipeline

One digest run (DigestRun Durable Object) Select a step to see its details.

Digest cron Prod off

Runs 40 minutes after the Dev publication; waits 15 minutes at a time, at most 4 times, while a publication is still running.

Sources: apps/data-publisher-worker/wrangler.development.jsonc, docs/runbooks/cloudflare-data-publisher.md

The day's snapshot

The digest pins one published release and never calls GitHub, Jira or the mailing list itself, so a run can be reproduced from its input.

Sources: docs/specs/014-topic-digest/spec.md

Select candidates

Threads with at least one human record in the 7 days ending at the release time; bot records are ignored.

Sources: packages/reference-pipeline/src/digest/candidates.ts

Classify by topic

@cf/cloudflare/clef-flash answers one multiple-choice question per thread: 12 topics (releases, clients, streams, KRaft, security, …) or routine maintenance.

Thresholds
routine section ≥ 0.6; a topic below 0.35 becomes Uncategorized
Cache
keyed by the classifier input and revision: an unchanged thread is not asked again

Sources: packages/reference-pipeline/src/digest/classify.ts

Score and place

Score = Σ 0.5^(age in days / 3.5) / k over human records, where k is the author's nth record in the thread, so one person repeating themselves counts less. Each thread lands in exactly one place: a card, routine or Uncategorized.

Sources: packages/reference-pipeline/src/digest/candidates.ts, packages/reference-pipeline/src/digest/mixing.ts

Summarize

@cf/meta/llama-3.3-70b-instruct-fp8-fast writes up to 3 sentences per card, 1 per KIP row, then a headline and 3 highlights. It only sees the selected threads, and every sentence must cite them, e.g. (KAFKA-PR-23829, closed).

Prompt
digest-prompts@4 (D98, 2026-10-20): status-faithful wording; "would" or "is proposed" for open, discussed or voted items

Sources: packages/reference-pipeline/src/digest/prompts.ts, apps/data-publisher-worker/src/digest/workers-ai.ts

Validate every sentence

Deterministic checks drop a sentence instead of publishing it: wrong length, no citation, a citation outside the inputs, a status word the source does not support ("merged" for an open PR, "verified" without a [RESULT] thread), a stance word ("objected", "rejected"), or a second proposal in one line. A card left empty shows "AI summary unavailable".

Last run
1 unparsable model output, 1 status:verified, 1 status:fixed
Tense rule
D97 on Dev since 2026-10-20: completion forms need a final cited item; tense:closed, tense:partial for [k/N] PRs; a modal earlier in the clause exempts

Sources: packages/reference-pipeline/src/digest/validate.ts

Translate to zh-Hant

@cf/qwen/qwen3-30b-a3b-fp8 translates the validated English in batches of 60. Identifiers, citations and links are swapped for placeholders first; if one is lost, the item stays in English and is labelled "Not translated".

Status guard
D99: on a status mismatch the item keeps English, counts translate:status-drift, and is not cached
Glossary
kafka-glossary@1 (D100): offloading → 卸載, telemetry → 遙測, …

Sources: packages/reference-pipeline/src/digest/protect.ts, packages/reference-pipeline/src/digest/translation.ts, packages/reference-pipeline/src/digest/profiles.ts

Write both locales

en.json, then zh-Hant.<hash>.json, then the pointer, so the site never shows a translation without its source.

Sources: apps/data-publisher-worker/src/digest/store.ts

Neuron ledger

Every model call is charged to a daily ledger before it is made; over 5,000 estimated neurons a UTC day the run stops. A second limit sits in AI Gateway: 60 requests an hour and $2 a month.

Sources: packages/reference-pipeline/src/digest/estimate.ts, docs/runbooks/cloudflare-data-publisher.md

English digest

What the quality gate reviews: cards, KIP block, headline and highlights, each sentence with its citations.

Sources: docs/specs/014-topic-digest/spec.md

Traditional Chinese

Item-for-item translation of the English digest.

Sources: docs/specs/014-topic-digest/spec.md

This week Dev only

Top to bottom: headline, window and stats, up to 3 highlights, KIP proposals by stage (discuss, vote, implementing), topic cards, then Uncategorized and Routine collapsed.

Sources: apps/web/src/components/digest/DigestWeek.vue

Quality gate not passed

A human labels one real week sentence by sentence; bun run digest -- eval counts the errors. Prod is enabled only when the thresholds are met.

English
status-mismatch 0, overbroad-stance 0 (fixed); others set by the owner
Translation
D102, decided 2026-10-20: status-drift 0, omission 0, term-error ≤ 2 per week

Sources: packages/reference-pipeline/src/digest/eval.ts, packages/reference-pipeline/scripts/digest.ts

Run numbers are from the Dev run of 2026-10-19 22:47 UTC (/health digest.lastRun, read 2026-10-20). Prod has the digest off.

Models run on Cloudflare Workers AI through AI Gateway (a proxy that adds rate and spend limits). The split of work is deliberate: a small, cheap classifier answers a multiple-choice question per thread; the large model writes only from the threads it was given; a third model translates. Ranking, placement and validation are plain code (Spec 014).

Why rules check the model

A design review of a real week of output (the week of 2026-10-08) found sentences that claimed a pull request was merged while it was still open, and that attributed objections nobody made. Prompting alone does not prevent this, so every sentence is checked against the source records before publication, and a failing sentence is dropped rather than repaired (validate.ts):

RejectionWhat it catches
lengthempty or over 240 characters
no-cites, cite-outside-inputsa sentence with no citation, or citing a record the model was not given
status:<word>"merged", "landed", "fixed" without a merged PR or resolved Jira issue; "released", "shipped" without an [ANNOUNCE]; "verified", "accepted" without a [RESULT] or [ANNOUNCE] thread
stance:<word>"objected", "rejected", "pushed back" and similar, which overstate a discussion
other-proposala second KIP in a line about one proposal
tense:<form>, tense:closed, tense:partiala completion form ("is added", "gets implemented", "now supports") when no cited item is final (a merged PR, a resolved Jira issue, a [RESULT] or [ANNOUNCE] thread); when a cited item is closed; or when the only final items are partial PRs ([1/N]) and the sentence does not say "first step" or "part k of"

The tense rule (D97, merged in PR #101 on 2026-10-20, running on Dev) exempts a form when a modal ("would", "will", "may", …) comes before it in the same clause, so "would be added" passes. The summarizer prompt was revised at the same time to ask for status-faithful wording (D98, digest-prompts@4); because the prompt revision is part of the cache key, the next Dev run (22:47 UTC) regenerates every sentence.

Translation status guard and glossary

Quality gate before Prod

The digest reaches Prod only after a human labels one real week and the evaluation meets the thresholds (Spec 014, Behavior 31).

Status as of 2026-10-20: the gate has not passed, so the digest runs on Dev only; DIGEST_ENABLED is unset on Prod (docs/feature-map.md).

Known limitations

Cost

ItemValueSource
Daily cap5,000 estimated neurons per UTC day (Dev and Prod)estimate.ts
Estimateprice table × 1.28, calibrated against the tokens Workers AI reportedSpec 014
Last Dev run29 model calls, 1,637 estimated neurons, 99 s (2026-10-19 22:47 UTC)Dev /health
Gateway60 requests an hour, $2 a month; a refused call ends the run as limitedrunbook

Caches keyed by input and revision mean an unchanged thread is neither classified nor summarised again; changing a prompt invalidates them, so the next run costs close to a cold run. bun run digest -- measure puts a cold run with digest-prompts@4 at 2,215 price-table neurons, about 2,835 estimated, within the 5,000 cap.