GET /api/feeds/{id}/entries for an OPML or a Patreon creator now lists the
items of the shows in it the person subscribes to, as All Subscriptions does
every feed's. The shows are looked up first and queried by list: an OR with a
subquery, or an IN over one, made a single feed's page a sequential scan of
entries (clarkesworld 10 ms to 26 ms or a second, EXPLAIN on production), so a
single feed keeps its `feed_id = $1`.
The page draws the OPML with its own header and the item list, tabs, search
and sort of any feed, with the feed column showing which show each is from.
A show's scan or change refreshes its OPML's list.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With the server paying for everyone's Signals, its bill had no names.
ipx_signals_judged_total, ipx_signals_hits_total and ipx_jev_tokens_total
now carry user (the account's name) and key (server or own); a call
shared on the server's key is split by each person's share of its
questions. Icon picks bill the person on the server's key, key checks on
their own. The dashboard has tokens and items by person and a Who used
what table over its range.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TypeSafe allows 80 requests and 100,000 input tokens a second. Six calls
in flight was a cap on concurrency, not rate: at 74 ms a call it is 81 a
second. Every call to Jev now takes a turn, a 60th of a second or its
guessed tokens' share of 80,000, so up to ten can be in flight. A 429
holds every call back for Retry-After and ends the pass. Each jev span
records paced_ms, /metrics ipx_jev_paced_seconds_total and a rate_limited
result, and the dashboard draws calls and tokens a second against the
limit.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The judge's query read all of entries (605 MB, 566 ms) on every wake; an
index on each feed's items by date, as the query asks, and the rechecks
in a half of their own. Calls ran one at a time, about 150 ms each, so a
new Signal's month of about 8,000 items took twenty minutes: six in flight
now. On the server's key everyone's Signals on an item share one call.
TypeSafe's token counts go to /metrics and each jev span.
An item's text is cut at 1,000 characters instead of 2,000: on 55 real
items of eight podcast feeds and six Signals, on the development key,
1,000 changed none of 330 verdicts (nor did the same request twice) and
saved 12% of the input tokens, 1,266 to 1,112 a call; 500 changed one.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs/signals.md says what the admin's setting does and that a key is
checked before it is saved; the install guide lists TYPESAFE_KEY; the API
reference has Signals' routes and types and the new fields of Me and
Settings; the home page says an admin may provide the key.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Neither orange tile nor orange icon on the tint worked, so each
Signal's tile is back in the theme's accent tint, as it was before
#268. The Signals folder icon and the larger DeadAir tile stay. The
tile rules go above the initials' comment, which they had split from
its rule.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A solid orange tile was too loud. Each Signal's tile is the folder's
accent tint again, and its icon or initials are drawn in the orange of
the Signals icon's point: #ff6a1a in dark. In light it is the light
palette's needle, #c43e00, since signals.svg's #ff5500 on the tint is
about 2:1, too faint for initials (about 3.4:1 instead).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
--accent2 mixed a quarter into the ground came out salmon, and is pink
or blue in other themes. Each Signal's tile is now solid #ff6a1a, or
#ff5500 in light, the point of signals.svg and signals-dark.svg, in
every theme as the icon is, with the icon or initials in the logo's
navy (#0c2238, 5:1 or better on either).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each Signal's tile, icon or initials, is tinted --accent2 in place of
--accent: the orange point of the Signals folder's own icon, so the
folder and what is in it read as one. The player's DeadAir tile goes
from 22px to 26px in its 30px button.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Jev chooses among options and cannot name one, so the page searches Font Awesome's index for each
word of the Signal's name, words and sentence, the best six each, and offers the likeliest 40.
POST /api/signals/icon asks a choice question on the server's TYPESAFE_KEY and answers with one
of those offered, never another. "Let Jev pick" in the icon picker, and a Signal made without an
icon gets one a moment after. Tried against TypeSafe: for AI Development, laptop-code 0.45 just
ahead of robot 0.40.
Each Signal's row says "12 items · 3 unread", as a feed's row counts its own, in place of its
words; /api/signals gives `items` beside `unread`, by the same rules as its list.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Jev was asked "Is this item about any of these: ai, development, programming?", so any one broad
word was enough and the Signal's name, which says what is meant, was never sent. AI Development
held 54 items: Sega pulling a game remaster (0.90), a Surface Laptop review (0.95), a C++ tutorial
(0.99). It is now asked about one subject, called by the Signal's name, described by its words
and, when those are not enough, its owner's sentence. Scored against TypeSafe over those 54 with
"AI tools for writing software: coding agents, AI dev tools, vibe coding, AI in code review.":
5 stay, Linux kernel AI code review highest at 0.94; the remaster 0.06, the C++ tutorial 0.02.
signals.description is new, and its first start deletes every verdict, which answered the old
question, so everything in the window is asked again. Any change to a Signal's name, words or
sentence drops its verdicts, since each is part of the question. The queue query names the
Signal's sentence apart from the item's description, which share a row; the test caught the
item's winning.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>