Skip to content

Releases: nlink-jp/news-digest

v0.3.0

Choose a tag to compare

@magifd2 magifd2 released this 09 Aug 00:52

Initial setup becomes something the agent can run.

Added

  • references/scheduled-operation.md — scheduled execution was how the skill was actually operated, and nothing in the repository described it. The file states the contract an unattended run relies on (skill by name, corpus by absolute path, non-interactive push, a reachable messaging tool), gives recipes for an app scheduled task and for cron, and orders the diagnosis when the digest stops arriving: transcript, then corpus log, then the schedule itself.

Changed

  • references/setting-up-a-corpus.md is now a runbook an agent can execute end-to-end, with the autonomy boundary stated first: the decisions only the user can make (interests, feeds, profile, destination, location) are collected in an explicit interview step, and everything after is mechanics. It also covers editing .newsrc.toml itself, creating the private remote and verifying the visibility actually is PRIVATE, and a supervised --dry-run first run as the gate before scheduling.
  • The skill description and routing now name first-time setup and scheduling, so a setup request triggers the skill instead of stopping at "no corpus found".

v0.2.1

Choose a tag to compare

@magifd2 magifd2 released this 08 Aug 09:14

A run clears its work directory before collecting, instead of being told to remove it afterwards.

The cleanup was an instruction in prose, and the first unattended run skipped it — leaving eighteen files behind, including message parts from an earlier, longer split. Those are the exact artefacts whose survival had already caused a bug: a sender walking msg-01, msg-02, … in order would have delivered two current messages followed by two from the previous run.

Clearing at the start rather than the end is the better half of the change. A run that dies partway leaves its files to be read, and the next run removes them, so the debugging value survives while a previous run's output can no longer be mistaken for this one's. --keep-work opts out.

The guard on that deletion now checks the root still holds a .newsrc.toml. Checking the work directory against the root, as first written, proves nothing: the two are derived from each other and stay consistent for any root at all, / included — which a test caught by trying to create a directory there. What is worth asserting before deleting a tree is that the evidence which justified operating on this corpus is still on disk.

No configuration change. Upgrading from 0.2.0 is a straight replacement.

v0.2.0

Choose a tag to compare

@magifd2 magifd2 released this 08 Aug 08:50

Three gaps a first unattended run found in a real corpus. All three are about the same thing: telling a permanent condition apart from today's news.

A source that cannot be read

body_fetchable = false marks a site that refuses automated retrieval as a standing policy. Previously every must-read from such a source came back unread, and validation — correctly, under the old rule — demanded an anomaly explaining why, every single day. A permanent condition reported as fresh news is noise, and it buries the anomalies that are news.

The run now skips the fetch it knows will fail, and the digest says which of the two applies: not retrieved today, or never will be. That difference is the whole of what a reader can act on.

A source that has stopped

Conditional GET, added in 0.1.0 to be polite, opened a hole: a frozen feed answers 304 forever, the error streak resets on every success, and probably_dead only ever counted errors. Two feeds in a real corpus had last published in 2025 and 2022 and looked perfectly healthy to every signal the tool had. A human caught them by reading timestamps.

Sources now report stale and stale_days against stale_after_days (default 60, per-source override — a quarterly advisory is not dead at 61 days).

A window wider than the feed

When every item a feed served fell inside the collection window, the window outran the feed's reach and there may have been more it never showed. Weaker than a gap — it says cannot tell, not lost — and it fired immediately on the one source the predecessor's README had warned about in prose: a feed that returns five items and loses the rest if you skip a day. That warning is now a signal.

Both new signals go to the operator, not into the digest's caveats. A feed frozen since 2022 is not missing today's news; it has none.

Upgrading

body_fetchable and stale_after_days are new keys in sources.toml. A corpus that uses them requires 0.2.0 — 0.1.0 rejects unknown keys rather than ignoring them.

v0.1.0

Choose a tag to compare

@magifd2 magifd2 released this 08 Aug 07:54

Claude Code Skill that collects your own feeds, decides what is worth reading, and compiles a digest of only that.

Code here, data elsewhere

The skill holds no data. Your feed list, relevance profile, and article corpus live in a separate repository you own and keep private — it names what you watch and what you care about. .newsrc.toml is the contract between them, and the skill refuses to run against a corpus version it does not support, so an engine update cannot quietly corrupt data it cannot see. One installed skill serves any number of corpora.

The agent never writes a priority

It scores three axes — novelty (against what is already known), significance (the world with the reader removed), relevance (their own contact with it) — and a script applies the profile's decision table. There is no field for a verdict, so a score and its verdict cannot disagree.

Profiles carry all the domain knowledge: the axes, the table, the rubric, the layout, and the shape the corpus's interests.toml must have. Ships generic and security-news, which extends it. Axis IDs are shared vocabulary, so tuning a rubric leaves an accumulated corpus comparable with itself.

What else it does

  • Keeps every collected article, including the ones a rule dropped, with the rule that dropped them
  • Tracks continuing stories, and names the ones that turned up again with no new facts — the record of why something did not need reading
  • Reports a collection gap when a feed has rolled past what was last collected, rather than letting the absence read as quiet news
  • Isolates article text in nonce-delimited tags before the agent sees it
  • Names a destination, not a transport: sending uses whatever messaging tool the agent can reach at run time

Python 3.11+, standard library only. No service, no database, no credentials.

Install

Unzip into ~/.claude/skills/, or upload the zip at claude.ai under Settings → Skills. Then create a corpus from examples/corpus/ — see references/setting-up-a-corpus.md.