Changelog
1,281 changes across 26 active days in the last 30.
Every line below is a commit message, published as written. Merge commits, tooling commits and planning notes are left out; nothing is summarised or rewritten. Today is still in progress and will grow until the next build.
Thursday 8 October 2026
Athenana
- Save to Athenana: name the host, not the title, and keep the copy a day
- Save to Athenana: clear the waiting link from superseded sign-up rows
- Save to Athenana: keep a stranger's link through sign-up
- MCP: drop wiki-link brackets from descriptions and summaries
- IndieAuth: the consent form may return to the client it validated
- Standards: a description that fits a search result
- MCP: a reconnection replaces by provenance, not by name; no single-label hosts
- MCP: exempt /mcp, /.well-known/ and /oauth/ from www->apex; name the library token
- MCP: a scope-less connector gets library:read, and the review's OAuth edges
- Privacy: recount the headings after the third-party list; widen the MCP read-only claim
- Privacy: name an AI assistant's company as the eleventh third party
- Say on the public pages that an assistant can read the library and change nothing
- MCP: a sign-in needs a handle, and loopback accepted narrowly
- MCP: no handle only for library:read, and four tighter OAuth edges
- MCP: sign in from Claude over the IndieAuth server
- MCP: every result fits 10,000 bytes; lapsed accounts may read
- MCP: POST /mcp with four read-only tools over the library
- Add the library:read permission for the MCP server
- Email to-dos: keep a subject's link in the title, and write down the re-read rule
- Email to-dos: on /features and /compare, held by a parity claim
- Email to-dos: keep Forgotten senders under Newsletters
- Email to-dos: the address on /settings/mail
- Email to-dos: a re-read leaves a marked or done note alone
- Email to-dos: a third address files a message on Today
- Inline images: fix final-review findings
- Inline photos: deterministic form ids, a picture note keeps its body, file dragover, panel alignment
- Inline photos: say what to do when pictures ride a non-note save
- Inline photos: Insert image, paste and drop in the note, text and annotation boxes
- Notes: edit the text after saving; a link's unnamed photos are deleted; tokens stay out of search
- Inline photos: a new note carries its pictures and rewrites its placeholders
- Inline photos: give the stranger's item an owner in the 404 test
- Inline photos: a JSON upload route for a saved note or link
- Reader: a note's inline photos show at the API address when asked
- Inline photos: every surface renders a note through ItemText, with its own address
- Inline photos: resolve photo: tokens to this item's own photos, per reader
- Plist work budget: 16 per object, not 8; the ceiling unchanged
- Parity: wyome names feed search and the Feeds page beside Discover
- Discover controls: review fixes
- Play buttons in feed search and on the Feeds page
- Discover: mute, boost or watch from the row
- Maps: count DrawMap in the third copy of the enrichment budget
- Maps: the Picture panel shows what public pages show, and the review's loose ends
- Privacy: say a saved map link's pin goes to Apple, and that it saves private
- Maps: an uploaded picture outranks the map on public surfaces too
- Maps: show the map on the board, the item page and, once published, in public
- Maps: draw a saved map link's pin with Apple and store it
- Maps: record confirmed Apple docs, guard truncated DER
- Maps: sign an Apple Maps snapshot URL for a pin
- Maps: a map link saves private, on every way in
- Maps: recognise a Google or Apple Maps link and read its pin
- Quick add: year-bound ISO dates, flash the year on a wrap, survive invalid UTF-8; stricter parity guard
- Quick add: on /features and /compare, held by a parity claim
- Quick add: refuse a line with nothing to do in it, and pin the reuse paths
- Quick add: a line on Today becomes a private to-do
- Quick add: trim link punctuation and sentence stops before dates
- Quick add: an exact set of trailing date phrases
- Document the DL-count limits; failed() for a vanished row; no global const in a test
- Measure the plist budget's headroom on a deduplicated build, limit 0.6
- BinaryPlist: an impossible member count is damaged before it is charged; pin the UTF-16 byte check
- ImportFormat: anchor the XML plist sniff at the start of the file
- NetscapeBookmarks: an unbalanced file keeps the rest private once a Reading List is entered
- NetscapeBookmarks: an attribute name does not match inside another's (data-id, data-href)
- RunBookmarkImport: failed() for a worker killed before its catch
- An XML-format Bookmarks.plist gets its own refusal sentence
- SafariReadingList: say 1980 in the date-window comment, and why
- SafariReadingListImportTest: declare its own helpers so it runs alone
- Pin the plist work budget's headroom on a 20,000-item file
- BinaryPlist: a string length past the file is damaged, not a budget overrun
- BinaryPlist: charge a collection before unpacking its references
- Items: the search_blob write stops stamping updated_at behind the model's back
- Sitemap test: pin the clock so the two updated_at stamps agree
- Checklists: count parses, not seconds, to prove the candidate cap
- Checklists: labels stop at a nested list, wire() checks the count, tidy-ups
- Checklists: a refused tick writes nothing, and set() checks the page too
- Checklists: a stale tick reloads the page instead of flashing
- Checklists: on /features and /compare, held by a parity claim
- Checklists: a locked toggle, and a click queue that survives a throw
- Checklists: tick without a reload
- Checklists: tick a box, refusing a stale note
- Checklists: the item page draws its boxes as buttons
- Checklists: an unplaceable box makes the note read-only, and set() checks its tick
- Checklists: TaskList, held to the renderer box by box
- Imports count the tags they applied, not the ones they asked for
- Watch email: a bounded window, no repeats, watches keyed by feed address
- Watch email: a daily digest of what your watch rules caught
- Bluesky: show a post left up wherever the item and the blog now are
- Bluesky: the whole-branch review's fixes
- Privacy: Sharing is the eleventh third party now
- Parity: the share-button matcher accepts the Share-block wording
- Privacy: Bluesky joins the third parties, and the share sentence says which block it is about
- Promises: say the server posts new blog posts to the owner's Bluesky, held to the code
- Bluesky: Try again keeps a maybe-sent row, aged or HTTP 5xx, so the command looks first
- Bluesky: opt a post out, delete it from Bluesky, try again, on the item page
- Bluesky reconcile: recognise an uncut link post by its words and card
- Bluesky reconcile: claim each post atomically; match the link-back only
- Bluesky: post the blog every five minutes, and withdraw what left it
- Bluesky record: a cut link links back; pictures upright and not black
- Bluesky: build the post record for one blog post
- Bluesky: never flash the app password, and throttle connecting
- Bluesky: connect an account with a handle and an app password
- Privacy: name Safari's Reading List as an import, and that it arrives private
- Correct two false comments in the Safari zip work
- Import Safari's Browsing Data export: ReadingList.html from the zip, private
- Safari Reading List: charge string bytes, cap dicts, refuse values the database would
- Import screen: the reading list tag follows the folders switch
- Say on the import screen how to bring in Safari's Reading List
- Import a Safari Reading List through the shared bookmark import
- Read Safari's Reading List out of Bookmarks.plist, private and dated
- Bound the plist reader's allocations, charge unpack work, refuse unrepresentable dates
- Read Apple's binary plist format, lazily and within bounds
- Discover briefing: paragraphs no longer depend on the model's line breaks
- AI: Haiku 5.5 replaces Haiku 4.5, as the default and for Hosted
- Item page: the due-date field adopts organic's .input, as settings fields do
- Do dates follow-up: due labels on /today, compact email row, visible Due label, /compare lastmod, notes
wyome.com
- Standards: stamp the page updated 8 October
- Privacy and standards: an AI assistant can read an Athenana library
- Privacy: feed search and the Feeds page carry the play buttons too
- Privacy: say a saved Athenana map link's pin goes to Apple
- Refresh the banked archive from the server
- Privacy: WyHealth works out a training plan and stores it with its inputs
- Refresh the banked archive from the server
- Privacy: Athenana can post a blog to Bluesky, and the Share block is per press
- Privacy: Safari's Reading List is an Athenana import, and arrives private
Wednesday 7 October 2026
Athenana
- Due dates: privacy section after the whole of 'Email you forward in'; reflow docblock
- Due dates: in the exports, on /features, /compare and the privacy page
- Due dates: the morning email's delivery gate, tested and checking status
- Due dates: the morning email
- Due dates: Today sorts by them, and the labels say so
- Due dates: set and clear on the item page
- Due dates: the columns, SetDo::due and the label
- Blog feeds: ask for the summary flag once a request, restore the owner-count test
- Blog feeds: carry a link's summary in place of its description
- Feed playback: the blog's JSON withholds a feed-saved episode's audio too
- Feed playback: an enclosure must be https, and a feed episode's note names the feed's address
- Parity: hold wyome's privacy page to the Discover play sentences
- Feed playback: a feed-saved episode plays for its owner only; the privacy page names Discover
- Feed playback: a player keeps its own keys, the parity facts see <source> and poster, the note says what is true
- Feed playback: press play on Discover, remember where you were, save keeps it playable
- Feed playback: pin enclosure clearing and the watch guard; refuse Unicode whitespace and a bare type
- Feed playback: enclosures captured and carried to Discover
- Compare: unique planner section id, drop a characterisation, link the fourth grid
- Features: the Do mark, held by a parity claim
- Compare: soften the planner prose to match the cells
- Compare: the planner grid
- Planner grid: the data, verified
- BlogFeedItemTest: name its asset helper apart from AssetServingTest's
- Portable blog: check blogIsLive() last in blogIsHidden() so only hidden owners pay for it
- Portable blog: gate post JSON on a live blog, don't forward a handle-less owner, carry photo pictures, drop duplicate covers, avoid N+1 on owner
- Privacy: the portable blog's feed carries everything but its summaries
- Promises: a portable blog on the privacy page, /compare and the parity tool
- Blog: a subscribe page of its own, reachable while the blog is hidden
- Hidden blog: forwarding, federation and sitemap tests
- Hidden blog: forward HTML pages to the owner's site; point url fields, directory, sitemap and digest at BlogUrls
- Blog: serve one post as a JSON Feed item at /s/{id}.json
- Blog JSON feed pages the whole archive and moves home while hidden
- BlogFeedItem test: tag names are stored lower-case
- BlogFeedItem: one published item as a complete JSON Feed item
- Portable blog: addresses, the switch, and BlogUrls
- Do mark: Undo from the Done tab goes back to it, and the review's minors
- Do mark: put the card's To do label in the foot, clear of the kicker
- Do mark: in both exports, off every public surface
- Today: assert the Back link label, not the sidebar's /today link
- Today: j and k walk the list the item was opened from
- Today: the To do and Done tabs, the bulk bar and the nav row
- Do mark: a To do label on the card and the row
- Do mark: the item page control
- Do mark: the columns and SetDo
- Reader API: cap uncached newsletter renders, anchor the parity claim, approved copy
- Reader API: standards section, features line, parity claim, knowledge note
- StoreItem: clamp a requested visibility to the type's ceiling
- Reader API: a star saves a private link, and an issue in the background
- Reader API: read, star saves, mark all read
- Reader API: subscriptions, folders and streams
- Reader API: ClientLogin is POST only, and the guards behind it
- Reader API: sign in with a Reader app token
- Mail budget: pin the sliding hour with a fixed-window reset case
- Blog email: keep a confirmed address, prune removed accounts' readers
- Blog digest: carry ids and decide again at delivery
- Mail budget: a sliding hour of per-minute buckets, and a confirmation tier
- Claims: say what blog email promises, on the privacy page, /compare and /features
- Task 7: Blog email housekeeping — prune expired sign-ups, unsubscribes and digests
- Blog digests: hourly athenana:send-blog-digests, claiming each day before it mails
- Blog email: put the confirmation under the transactional mail theme test
- Mail: the blog digest, its views, and DigestBody
- Blog email: the owner's switch and a subscriber count, never an address
- Blog email: one answer for missing, oversized and array input; 404 confirm for a removed blog
- Blog email: subscribe box, confirmation mail, confirm and one-click unsubscribe
- Blog email: subscriber and digest tables, models, shared token trait
- Mail: back off and cap exceptions on budgeted mailables
- Mail: an outbound budget so every email stays under the 100-an-hour cap
- Item page: Pin to top of the blog joins the action row; Schedule sits on the inputs' line
- Newsletters: prune emptied senders, say forgotten senders are listed, guard the 90-day claim
- Privacy: the newsletter address keeps issues and senders 90 days, fetches nothing until saved
- Newsletters: Back stays on this app; knowledge note for newsletter capture
- Newsletters: a gone issue is refused, and a saved one is seen
- Newsletters: read an issue here, save it as a note, forget a sender
- Newsletters: no stored mail outlives its account or its sender
- Newsletters: issues arrive in the pool, kept 90 days, never fetched
- Mail: the note-making tail is one callable, NoteFromMessage
- Newsletters: a second address, beside the forwarding one
- Tests: WatchTest makes its account on the travelled clock
- Safari release: unregister the export and archive copies after stapling
- Safari build: --install unregisters the export and archive copies
- Privacy: Safari's watch check sends no sign-in; one check fetch at pick time
- Extension: a harmless redirect is not a sign-in wall; readers share offscreen
- Extension: Confirm verifies a watch with one quiet fetch; Safari fixes
- Extension: page watch runs on Mac Safari, through a background page
- Revisit: follow the board's list / board layout
- IndieAuth: a sign-in from our app revokes its stale app tokens
- Blog composer: final review fixes (pinned-only page 2, pinned kicker colour, doubled errors, pin guards, tidy)
- Public claims: correct scheduling wording and record the flip
- Public claims: blog scheduling, pinning and about page now ship
- Export: blogged, scheduled and pinned in front matter, CSV columns, about.md
- Blog about page, actor summary, sitemap entry and timezone setting
- ActivityPub: a featured collection for the pinned post
- Pin to top of the blog: one post held first on page one, never duplicated
- Blog: list scheduled items on What's public, with cancel
- Blog: athenana:publish-scheduled applies due schedules every minute
- Blog: schedule a publish from the item page, and cancel it
- Blog composer: clear schedules and pins when changing visibility
- Blog surfaces order and date posts by the publish date
- Blog: blogged_at, the day a post went out, and blogIsLive()
- Refuse five.co.in referrals, matching wyome.com's block
WyHealth
- Detect the lab results cap from the total count, not an extra row
Wy5
- Declare name and coarse location in the privacy manifest
- Show the leader's first-place share, and say what the off-consensus count counts
- Add DEBUG launch arguments for reaching screens and a local server
- Quote ssh arguments in deploy.sh, and create the staging directory remotely
- Refuse five.co.in referrals, matching wyome.com's block
WyAuto
- Tell the pump scanner's user how to beat glare, and say so in the listing
WyHome
- Fit main's new harness and CLAUDE.md to iCloud sync
wyome.com
- Privacy: Discover's play buttons, and a feed-saved episode stays off public pages
- Stamp the stylesheet
- Blog: the pinned post cannot vanish, a tag walk waits for a page in flight
- Blog: one feed page on load, older posts on request, a 40-tag cloud
- Blog: never walk a feed page twice, and no failure links that loop
- Blog: read everything the portable feed carries
- Standards: Athenana syncs with news readers over the Google Reader API
- Privacy: a blog on Athenana can offer its posts by email
- Privacy: a forgotten newsletter sender stays on a block list until undone
- Privacy: a second Athenana address keeps newsletter issues, 90 days, nothing fetched until saved
- Privacy: Safari's watch check sends no sign-in; one check fetch at pick time
- Refuse five.co.in, which launders referrals through redirect.php?ref_host=
Tuesday 6 October 2026
Athenana
- iOS: the waiting screen says subscribe, and Check again says what it is for
- iOS: the waiting screen's store opens as a sheet behind "See plans"
- Sign-in from the app, already signed in on the web, goes on to the app
- Compare: a third grid, against six blogging platforms
- Pricing and terms: the iPhone app sells both plans monthly
- Discover row: one data-key-open anchor; put withoutWatches under its own docblock
- Page watch: drop link-less items, keep watches out of the briefing, small review fixes
- Privacy: put the watched-site clause where it reads naturally
- Page watch: resolve links against the redirected URL, count only accepted checks, abort stalled reads, require Chrome 116
- Privacy: say what the extension's page watch fetches and when
- Page watch: the browser re-checks watched pages
- Page watch: choose the item link, ignore synthetic events
- Page watch: pick a repeating item on the page
- Page watch: race-safe inserts, stronger prune test, input caps
- Page watch: the API the extension writes through
- Page watch: no summaries, no reader, 255-character titles for watches
- Page watch: a watch kind of feed the server never fetches
- Search: pool blank flag from PoolSearch, and the missing save and cap tests
- Search: in:feeds results on the board, with Save
- Search: push pool date and site filters into SQL, cap when a source is full
- Search: in:feeds finds the feed pool, newest first, muted left out
- Regular feeds: review minors (docblock order, wording, route comments, limit tests)
- Regular feeds: style the page like Feeds, with bulk Forget
- Feed rules: fix Steer form layout at 375px, tidy review findings
- Discover rules: in the export, beside saved searches
- Discover rules: write them on the topics screen, and see what they hid
- Tests: move the steer* fixtures to Pest.php so each file runs alone
- Discover rules: a boost puts up to three stories first, and says so
- Discover rules: a mute keeps a story off both lists and out of the briefing
- Discover rules: a feed rule stores the feed id, not its title
- Discover rules: the tables and the one matcher
- Compare: a second grid against six feed readers
- Say at the top of an item when the site blocked the server
- Privacy: fit the meta description in 160, pin the visit wording
- Front page: people sharing and visits; visits on a link's own page
- Discover reader: b goes back to the story you opened, not the top of the list
WyHealth
- Keep lab figures as written, and tighten the copy and reads
- Show lab results on the dashboard, flagged against the lab's own range
- Save only after the form has hydrated, and let React set the method
- Keep the no-JS POST fallback on the lab form
- Keep the form's selections after a failed save, and give /labs the brand face
- Add the pages for entering, editing and deleting lab draws
- Read and write lab data, telling a failed read from an empty one
- Name the lab constraints, refuse non-finite values, and test every cross-user path
- Store lab draws and results as entered, editable only by their owner
- Write the labs copy, held to the banned-vocabulary list
- Reject impossible dates and loose numbers, and break ties by id
- Flag results against the lab's range, validate panels, and build marker rows
- Add the lab marker catalogue and its unit conversions
- Start Apple sign-in on the server, and say when it fails
- Name the last two chosen limits, and keep the zones sweep fast
- Plan from what was actually done, and guard its inputs
Wy5
- Bound Apple's share of an account deletion to nine seconds
- Refuse a second group's copy of a topic, and name the unindexable-title error
- Refuse to upload ahead of migrations, and let /health see every one
- Stop list restore re-requesting topics the server refuses at every launch
- Say an edited list's earlier version still counts, and why a search failed
- Show the server's own message for invalid_field, and name an unindexable title
- Let account deletion proceed when Apple's confirmation sheet fails
- Score group boards by each pick's stored rank, not its position
- Swap deploys in atomically, keep credentials off the command line, and record migrations
- Stop timestamps depending on two clocks agreeing, and make /health real
- Meter every write per user, read by user, and raise Browse's trending cap
- Report Apple revocation truthfully, and harden sign-in and sign-out
- Keep the synthetic catalogue and slug fixtures out of Release
- Add blocking, content reports, re-authenticated deletion and honest errors
- Show only Commons thumbnails, and give Wikimedia a support contact
- Make coloured text readable in both appearances and at large type
- Keep reports after their group is gone, report content too, and mail every one
- Let a member block another, one-way, from what they see
- Keep a group's topics inside the group, and withhold standings below three lists
- Stop a ballot rewriting shared catalogue items, and check new ones with Wikidata
- Declare privacy, encryption and orientation for App Store submission
- Filter user-generated text, and refuse a second copy of a member's name
- Ship Wy5 free, with no in-app purchase
WyHome
- Keep a recorded standing across coalesced passes; clear denial on return
- Make Sync now report what each channel actually did
- Say why a mirroring toggle bounced off when access is denied
- Leave another device's placeholder alone when repairing identifiers
- Claim a mirroring channel only if the toggle is still on
wyome.com
- Privacy: the watch check also sends a short excerpt of each item
- Privacy: the Athenana extension re-checks pages you ask it to watch
- Describe what Wy5 actually stores, and keep its join codes off the stats page
- Publish terms of use for Wy5, linked from every page's footer
- Refresh the banked archive from the server
- Privacy: Athenana counts page visits too
Monday 5 October 2026
Athenana
- Regular feeds: say plainly when a Flipboard feed is not fetched
- Regular feeds: correct the comments the branch made false
- Regular feeds: say when one fails, on the page and in the command
- Regular feeds: prune on every exit of the Discover build
- Regular feeds: a lost double submit is a duplicate, and keeps the subscription
- Regular feeds: add and remove them by hand, on their own page
- Regular feeds: leave Flipboard's aggregations out
- Privacy: say that feeds read elsewhere are fetched for Regular feeds
- Discover: Save on a Regular feeds row returns to that tab
- Discover: a Regular feeds tab, with the reader's way back to it
- Discover: make the regular-failure test discriminate, and log when the list is capped
- Discover: build each morning's Regular feeds list and its briefing
- Discover: one place stores a day's list, for a second list to share
- Discover: make the list-separation tests discriminate
- Discover: a row and a briefing belong to a list, and every read names it
- Feeds: fetch the feeds read elsewhere nightly, and keep them ignored
- Feeds: an ignored feed can hold entries, for the Regular feeds tab
- Feeds: one fetch-and-parse core, for a second kind of feed to share
wyome.com
- Refresh the banked archive from the server
- Privacy: feeds read elsewhere are fetched for Regular feeds
Sunday 4 October 2026
Athenana
- Discover reader: remember a Google miss for a day, resolve before a stale copy
- Privacy: opening a Google News story asks Google where it lives
- Discover reader: say why a story can't be read, and read Google News stories
- Discover: decode Google's answer rather than matching it
- Discover: turn a Google News link into the publisher's address
- Mac: a UI test for the refused-save notice in the library window
- Discover reader: b goes back to the Discover list
- Discover: bound the picture proxy, and keep a day to a day
- Privacy: say that a Discover story opened here is fetched by the server
- Discover: Save keeps the copy that was read
- Discover: a story's title opens it here, with pictures through a signed proxy
- Discover: fetch a story when it is opened, and keep it for a day
- RawHtmlArchive: an empty kept copy is no copy
- FetchPage keeps a page the Discover reader already holds
- Reader: one public extract-and-finish chain, for a second reader to share
- Board edit: after Delete, return to the board's first page, not the one scrolled to
- iOS UI test: the refused-save waiting-screen test launches pending
- iOS: "Create an account" on the sign-in screen opens the app's sign-up
- Sign-in from the iPhone app carries no route to a purchase outside it
- Board edit: Delete stays on the right when pressed, and is a filled button
- Board edit: reach pages infinite scroll appends, and keep the ring inside the card
- Board: an Edit mode that selects cards or rows and trashes them together
- Knowledge: final-review fix wave (policy-parity concept, okf.py escapes and ---, pointers, descriptions)
- Knowledge bundle: coverage accepts per occurrence and counts short lines
- Knowledge bundle: okf.py coverage proves a move dropped nothing
- Knowledge bundle: tools/okf.py index and check, with tests
- Webmentions: a target that dies mid-read costs one mention, not the run
- Discover: search the kept daily briefings, and say that is all it searches
- Disk check: the ratio test proves the trash is counted
- Disk check: count the feed pictures in the files stored
- Disk check: one mail per mailbox, whatever the case
- Disk check: the remembered band only rises
- Disk check: send the alert at once, and record it only once it went
- Disk check: mail the operator at 70% and 85% used, nightly
- Apple News: a story only in News has no article, not Apple's notice
- iOS release: require the real subscription group id
- Apple News: read the publisher's page, not Apple's redirect page
- Apple's two routes join RawBodyRoutes: bounded before any decode
- Apple IAP: the unlock route decides "mine" by the writer's owner rule (N1)
WyHealth
- Stack the empty-state lines, and keep the windows DST-safe
- Show this week's training plan on the dashboard
- Store each plan with the inputs it came from, readable only by its owner
- Treat a failed read as a failure, and name every chosen number
- Decide when a plan stands and say why it changed, in vetted words
- Derive the plan's inputs and generate a plan, or say what is missing
- Keep the long session the longest, and pin the volume promises
- Ramp weekly volume 10 % at a time and split it into sessions
- Add the plan engine's types and heart-rate-reserve zones
WyAuto
- Hold Save while a picked receipt photo is still loading
- Show a receipt at its actual size when zoomed to full size
- Run one reminder rebuild at a time, the latest winning
- Read only a definitive 4xx as no such vehicle
- Test the upgrade from a store written before versioning
- Rebuild reminders after every change that moves one
- Keep the source-root constant off the main actor so the tests compile
- Add CLAUDE.md, describe the hook generically, mark the tier docs superseded
- Warn on an odometer jump no one could drive
- Read a 4xx as no such vehicle, and drop superseded lookups
- Say when the camera fails, and offer to type the figure instead
- Describe the Reports charts and the camera view to VoiceOver
- Let a saved receipt be viewed full size and removed
- Downscale receipts at ingest and stop decoding them in body
- Turn the reminder switch off when iOS has notifications denied
- Remind about due-soon and overdue rules, at 9:00, on every foreground
- Say plainly what the store failure means and what to do
- Skip the schema source scan where the sources are not on disk
- Version the SwiftData schema and show a store failure instead of crashing
- Add picked photos to the pending images instead of replacing them
- Write numbers back into editable fields in the locale Parse reads
WyHome
- Say when iCloud status is unavailable; note the sync loop's limits
- Claim a mirroring channel only once access is granted
- Give a restored or migrated device its own ID
- Ship the remote-notification background mode in the iOS app
- Fold a placeholder only into an older property, and only on its maker
- Correct the schema deploy guidance and tidy the initializer
- Add a CloudKit schema initializer, cap attached files, document sync
- Count only successful imports; treat transient iCloud states as unknown
- Sync records through iCloud
- Describe the pre-push hook for this repo, not another project's incident
- Test recurrence, schedule and search-radius logic with fixed clocks
- Never sweep a calendar WyHome does not own; read identifiers after commit
- Tag mirrored identifiers by device and sweep what no record points at
- Let one device own each mirroring channel
- Fold the auto-created "My Home" into the real property
- Add the pure rules behind iCloud sync, with a harness
- Ignore in-repo worktrees
wyome.com
- Privacy: a page Athenana cannot read offers a link to the publisher
- Privacy: opening a Google News story asks Google where it lives
- Privacy: a Mac keeps WyHome's data after the app is trashed
- Privacy: WyHome records sync through the person's own iCloud
- Privacy: opening a Discover story in Athenana is fetched by the server
- Refresh the banked archive from the server
Saturday 3 October 2026
Athenana
- iOS: Restore asks again past a refusal, and says when it finds nothing
- Apple IAP final fix wave: approved copy, 503 for unrecorded purchases, quiet updated_at
- Feed article: follow an Apple News share, and ask the owner's feeds when a page names none
- Remove the tag that was pressed, not the board's tag
- iOS: Restore, Terms and Privacy outside the store view; sharper guard
- iOS: the subscription screen, on the waiting screen, the menu and a refusal
- iOS: end a purchase listener with its account
- iOS: finish a purchase only on a refusal of the purchase itself
- iOS: StoreKit 2 purchases, posted to the server and finished on its answer
- iOS: drop a purchase's answer that outlives its account
- iOS: read /me whole and post a purchase's signed transaction
- Billing: stable switch key, live channel for card declines, device-neutral cancel sentence
- Billing: acknowledgment, reminders and standing emails for Apple subscribers
- Billing: reconcile fix round, sandbox expiry stated, dry run and unmatched rows honest
- Billing: athenana:reconcile-apple, the Apple half of the nightly reconcile
- Decode no stranger's JSON before a ceiling can refuse it
- Billing: queue the two-subscriptions notice, split the admin ledes
- Billing: say so when an account pays twice, and show Apple on /admin/users
- Billing: a double subscriber keeps Manage billing and loses the switch
- Billing: the web offers an App Store subscriber no checkout
- Billing: bound the unlock body before anything decodes it; no store for an admin
- Billing: /me names the purchase token and channel; the app's unlock route
- Billing: refuse an oversized Apple notification before anything decodes it
- Billing: receive App Store Server Notifications V2
- Billing: decide an Apple subscription's ordering in the database
- Billing: record an Apple subscription and admit its owner
- Billing: AccountStanding reads Apple subscriptions beside Stripe's
- Billing: every App Store Server API failure is AppStoreUnavailable
- Billing: read a subscription's status from the App Store Server API
- Billing: the Apple tables, the account token and the product map
- Billing: globalise the Apple test helpers, test forged chains under the real root
- Billing: verify Apple's signed data against a pinned Apple Root CA G3
- Round six low: the web holding page says the account isn't open yet
- Round six low: the Mac library shows a refused queued save's sentence
- Round six low: the call site's file-URL flag is pinned, not only its rule
- Round six low: the migration compares the old stamp with the signed-in account
- Round six low: the Read menu's Open Original takes the toolbar's rule
- Round six low: a web address beside the link is the link, not a quote
- Round six low: the outbox migration carries only this account's old entries
- Round six low: the Mac opens an original only when it is a web address
- Round six low: a picture whose file cannot be read is never loaded whole
- Round six low: the waiting screen says the account isn't open yet
- Round six low: a refused token stops the outbox replay and signs out
- Round six low: the MyMind PDF's temporary copy never outlives the import
- Round six low: the pending-deletion exemption is free access the account has now
- Round six low: a won dispute does not cost the month carry
- Round six low: pin callsModel() across every enrichment stage
- Round six low: every reader takes the subscription derive() takes
- Round six low: a MyMind import's kept PDF counts against the storage cap
- Round six low: the pending-account purge spares a live grant
- Round six low: a lapse ends the month carry
- Round six low: a purged item keeps its tag and image slot for the month
- Round six low: no model call for an item whose owner was removed
- Round six low: refuse the Portal while any dispute is open, granted or not
- Round six low: record the renewal's period end before the standing reads it
- Round six low: a charging subscription outranks a newer one that ended
- Round six low: the sign-up maximum fill time is floored above the minimum
- Round six low: the feed-extras claim follows the flag into key()
- Round six low: the referrer-spam skip fires only on an address-served site
- Round six low: suspending a paying account says its billing goes on
- Round six low: a site's own clicks skip the referrer-spam block
- Round six low: a suspended session is signed out of /pending
- Round six low: a sign-up form's signed stamp has a maximum age
- Round six low: every sign-up outcome but a bot spends the global cap
- Round six low: the feed-extras claim checks each call asks for extras
- Round six low: restore lifts a suspension and approves nothing
- Round six low: the reading API deals by the switches the screen offers
- Round six low: a replayed save is the duplicate, not refused at the cap
- CLAUDE.md: www and scheme folded in match(), the 555 unit change is hygiene
- Feed article: measure as the reader does, keep less, fold www and scheme
- Feed article: a new feed copy drops the stored pictures, and the backfill re-images
- CLAUDE.md: the reader asks the site's feed first; the 555 budget everywhere
- athenana:backfill-feed-articles: one host, each feed fetched once
- ReadableArticle: put the raw-markup warning on the public chooser
- Reader: use the feed's article unless it is only an excerpt
- Enrichment: keep the feed's copy of a saved article
- Find a saved page's article in the feeds it advertises
- Feeds: keep each entry's full content beside its summary
- Tag board: Jump to offers related tags, not the most used
- Round six: one vanished checkout or subscription no longer skips the rest
- Round six: the prune leaves a row a webhook wrote after its Stripe read
- Round six: a created event Stripe has already cancelled gets an end date
- Round six: a past_due subscription's unpaid invoice may still be charged, and the screens say so
- Round six: an abandoned checkout beside a grant is not "still billed"
- Round six: a stray is re-checked against live accounts at the moment it is cancelled
- Round six: an open checkout cannot outlive the account it would charge
- Round six: a granted account that pays is told so, and can stop paying
- Round six: a subscription webhook writes Stripe's current state, not the payload's
- Round six: the lapsed prune asks Stripe before it deletes a payer
- Round six: a grant releases held saves, through the payer's own step
- Round six: lapse only on an open latest invoice
- Round six review: the allowance claim checks the Retry form, and /pricing covers the year
- Round six review: every deletion sentence reads its days from config, and names the dispute
- Round six review: a price-check verdict is about the config it judged
- Round six review: the Switch to Hosted is held to the price check too
- Round six review: count only previews a person sent, not one the server fetched
- Round six: say on /terms and in the free-access emails that a lapse ends in deletion
- Round six: check the advertised prices against Stripe, and pause checkout on a mismatch
- Round six: an uploaded preview counts against the storage cap
- Round six: an API 402 names no website, plan or checkout
- Round six: /pricing no longer promises that capped saves are read later
- Accessibility review fixes: skip links, main landmarks, a shortcut off switch
- Tumblr import: escape !, ~~ and & so a body renders as written
- Tumblr import: route the job, name it on Sharing In, and write it down
- Tumblr import: every post a private, pending item
- Tumblr import: a damaged zip entry is a sentence or a null, and the temp copy never leaks
- Tumblr import: open the export in any of its three measured shapes
- Tumblr import: read one post file, from the measured template
- Tumblr import: linear emphasis edges, break-safe emphasis, more block elements
- Tumblr import: a post body into Markdown, by allowlist
- iOS capture: text that is only a web address is a link, not a note
WyHealth
- Close the final review: pre/post-push checks, rollback, and comment fixes
- Tell an RLS refusal from a missing grant, and check prod holds 0019's
- Grant each table's privileges explicitly, and anon none
- Build a database from the migrations alone and hold it to a grant matrix
WyAuto
- Stack the Log and Coming-due rows at accessibility text sizes
- Stack the Garage row's figures at large accessibility text sizes
- Tell an unreachable lookup apart from one that found nothing
- Drop the last free-tier and paid-path wording from comments; README test count
- Show the scan buttons before camera permission has been asked
- Draft the App Store listing, capture screenshots, and correct two claims
- Add the privacy manifest and export-compliance flag for submission
- Sell WyAuto for $1.99 with every feature included
WyHome
- Give VoiceOver the state of the remaining job checkboxes
- Give VoiceOver a name for the intake checkbox and every form text field
- Stop the visit row's long-press preview clipping its first letter
- Offer the search radius in the units the results are shown in
- Shorten the intake title on iPhone so it fits beside its buttons
- Remove stale copies of intake sources from the repo root
- Read properties in display order where the first one matters
- Leave the dryer vent off the demo schedule
- Open documents in a page-sized sheet on iPad
- Say "Every year", not "Every 1 years", in the job editor
- Stop the Maintenance due-soon tile counting overdue jobs
- Scope the six-month chart on Today to the selected property
- Add a DEBUG-only demo store for screenshots
- Close three open items from the visits merge
- Add the privacy manifest App Store Connect requires
- Sell WyHome for $4.99 up front and drop the subscription
wyome.com
- Privacy: an Athenana plan can be an App Store subscription sold by Apple
- Privacy: WyAuto syncs through iCloud and looks vehicles up with NHTSA and the EPA
- Privacy: an unopened Athenana account with free access from us is not deleted at 30 days
- Privacy: an unopened Athenana account with free access from us is not deleted at 30 days
- Refresh the banked archive from the server
- Accessibility review fixes: contrast, a main landmark, no timed refresh
Thursday 1 October 2026
Athenana
- Deck settings: stop offering the two switches the apps can no longer deal
- Serve .webp as image/webp
- Features: drop the phone tile, and show the reader's article text
- Features: show the product in the hero, from a staged demo library
- Billing: show a pending plan change scheduled in Stripe
- Mail: every email wears the weekly newsletter's look, and fetches nothing
- Billing: Switch to Hosted asks for confirmation before it charges
- Refuse referrer spam ahead of everything else, copied from wyome.com's block
- Billing: after paying for Own key, land on the key screen with a welcome panel
- Pending: the full wordmark at every width
- Pending: no sidebar, so the page centres in the window
- Pending: one page with the price grid, not eight stacked cards
- Open registration review fixes: pending and suspended API refusals worded apart
- Open registration: an account opens when it subscribes, and an invite with a plan opens at once
- Tags: one tab strip across Tags, Manage and Suggested
- Admin: the members table gets the full width; empty dispute lists are a plain line
- Pricing: name the Hosted model as Claude Haiku, without the version
- Parity: pin call sites and one answer; record the rulings
- Sign-up: four abuse protections, the pending flash, one error, the nav pair
Wy5
- Refuse referrer spam at the API docroot, copied from wyome.com's block
wyome.com
- Refuse the outreach-link-building campaign by its path, and two more hosts by name
- Athenana: an account opens when it subscribes
Wednesday 30 September 2026
Athenana
- Records: the third retirement, the pricing page, and the claims that hold them
- Claims: sign-up and the Hosted extras, held to the code on every page that makes them
- Front page: a pricing band below Recently saved, alternating in both states
- Pricing: fit the public top bar on one row, and assert the allowance by sentence
- Pricing: a public page, from one price source and the config the plans enforce
- Sign-up: re-check the address under lock inside the claim, and print a refusal once
- Sign-up: the link's page creates a pending account, and nothing else does
- Sign-up: one answer for every address, a queued link, and three throttles
- Sign-up: a links table that creates no account, and its nightly prune
- Billing: state the hosted model by its public name, from the one pin
- Billing: one source for the four prices, and the facts a pricing page states
- Reconcile and acknowledgment: review fixes I1-I4 and minors
- Billing: withhold the acknowledgment from a refunded, cancelled subscription
- Reconcile: approve paying accounts, sweep unknown subscriptions, apply disputes
- Share sheet: ask a declared picture's file-url item and its NSImage before refusing
- Share sheet: read a declared picture through its file representation, and say so when nothing can
- Mac share: the regenerated Info.plist carries "Save to Athenana"
- Share sheet: a bare file URL to a picture is that picture, and the Mac logs what it is handed
- Mac share: the extension is "Save to Athenana", not a second "Athenana"
- Mac share: review fixes — refuse the unprovisioned install, probe first
- Mac: a share extension, "Save to Athenana" in every app's Share menu
- Mac: one shared group for the token and the outbox, and a one-time move
- Mac: the share sheet's decisions compile and pass on macOS
- CSP: let Subscribe and Manage billing redirect to Stripe
- Merge fix: price Sonnet 5.5 where the branch priced Sonnet 5
- Step 6 review: say which fraud warnings are refunded, date the privacy page today
- Billing step 6: privacy and pricing wording, seven parity claims, delete subscription rows with the account
- Billing 5C follow-ups: disputed deletion wording, no-email log split, grant tie-break, pass-2 catch test, records
- Billing 5C fix wave: warn and prune disputed accounts, gate the prune on the final warning, catch per-notice failures
- Picture panel: let the server judge a pasted image address
- Picture panel: stop nesting forms, so the URL box submits again
- Billing: reconcile survives stored period ends, trashed owners and wider outages
- Billing: nightly reconcile against Stripe, and prune long-lapsed accounts
- Billing: pin the deletion-day boundary and skip grant notices for accounts that keep a plan
- Billing: send the free-access-ending and deletion-warning notices
- Billing: an abandoned new checkout does not hide the lapse behind it
- Billing: queue the standing emails, narrow the free-ended case, quiet EFW lapse
- Billing: email on card declined, lapse and the end of free access
- Billing notices: key on a subject, so a grant or an account can have one
- Billing: lapse clock survives disputes and abandoned checkouts; column migration runs before the backfill
- Billing: lapsed_since and a standing-changed event
- Smoke: hold the anchored pass and position exemption
- Standing: honest copy for uncovered podcast accounts and expired free grants; comment fixes
- API: anchor the pass and position exemption so a share target cannot ride it
- Billing: no nightly discovery build or feed refresh outside good standing
- Billing: release held saves when an approved account first reaches good standing
- Webmentions: renewal reopens the withdrawn ledger row
- Mac: the reading keys work while an article is loading
- Mac: put the reader's toolbar at the window's trailing edge
- Lapsed gate: a Kindle job queued before the lapse refuses at run time
- Podcast: the operator's credential is for admins and grants, and a lapsed feed is a 404
- Lapsed gate fix round 1: account and item screens name the archive, not 'publishing is off'
- Lapsed gate: an account out of good standing is archived on every public surface
- Lapsed gate: keep a lapsed account's backlog un-stamped, and fold in review minors
- Lapsed gate: AI, mail, imports and MyMind stop for an account not in good standing
- Lapsed gate fix round 1: pass/position open, Micropub trash closed
- Lapsed gate: 402 on the API and Micropub create/update
- Lapsed gate fix round 1: banner for approved accounts only, narrower OPEN, secret removal stays open
- Revert the Mac title-bar change (11fc3bb4)
- Lapsed gate: the web middleware, the export list and the standing banner
- iOS on a Mac: no "Athenana" in the title bar, and the window takes the ground
- Billing: the standing predicate, its scope, and a backfill of billing_state
wyome.com
- Say that anyone can create an account with an email address
- Privacy: WyHealth still signs in with Apple only; date today
- Privacy: paid Athenana plans, Stripe, billing records, lapse and deletion; correct the sign-in sentence
- Changelog: read each project's upstream as well as its checkout
- Refresh the banked archive from the server
Tuesday 29 September 2026
Athenana
- Mac: the reader's head carries the details; no inspector, no title, search lets go
- iOS: dropped-save notice follow-ups from the final review
- iOS: an in-flight replay's refusal cannot outlive sign-out
- Mac UI tests: pin the reader's typography, not inherit the owner's
- Mac: the list draws its own selection, and its type is smaller
- iOS: stage a refused queued save in fixture mode, test and screenshot the dropped-save notice
- Account: give the Your data panel the #export anchor the app links to
- iOS: Export your library in the account menu
- Picture by address: say to upload it when a site refuses the server
- Outbox: do not report a refusal through onDrop once purged
- iOS: show the server's sentence when a queued save is refused on replay
- Mac: the list column takes the card colour, not a grey
- Extension: state a 402 or 413 as the server's own sentence
- Billing: the fraud email names a denied account and says what this run did
- Billing: a skipped fraud warning records its account and amount
- Billing: refuse the Portal on the server while a payment is disputed
- Billing: a lost dispute lifts only once a renewal is paid after it
- Admin evidence: no after-charge figures without a charge date, and reach disputes on removed accounts
- Admin: list disputes and fraud warnings, and print the evidence for a dispute
- Billing: run the early fraud checks before claiming the row
- Billing: finish an early fraud refund that failed after the money moved
- Billing: refund an actionable early fraud warning and cancel at once
- Mac: a held space does not repeat, and CLAUDE.md says where the keys go
- Billing: closed disputes stay closed, open events stop renewal, paying again clears a lost dispute
- Mac: a reading key works on every press, not only the first
- Billing: record disputes, stop renewal, read disputed
- Admin step-up stamps the session without logging a sign-in
- Log sign-ins (time and method, no IP) for the dispute evidence packet
- Mac: an app icon, a grey list column, and a wider one
- Keep denied payers in Paid, not admitted; terms says about a month
- Admin: denying an account cancels its Stripe subscription first
- Billing: the monthly plan's yearly reminder names no date in its subject
- Billing: back the acknowledgment job off so a short outage cannot lose it
- Guard against changing a subscriber's price; record step 4B
- Billing: a dry run must not spend the missed-window alert
- Billing: send the advance renewal reminders
- Billing: make the acknowledgment's failure tests discriminate
- Billing: acknowledge a first payment or a switch by email, once per invoice
- Billing: record the checkout consent, with the words shown
- Billing: record the Stripe period end and show "Renews on"/"Ends on"
- Billing: a terms page, and the support address from config
- Mac: an empty library says "Nothing saved yet."
- Mac: the list's last line says what kind of end it is
- AI: Sonnet 5.5 replaces Sonnet 5 as the default and the account choice
- Settings sidebar: a Billing row below Account
wyome.com
- Refresh the banked archive from the server
Monday 28 September 2026
Athenana
- Billing: account deletion cancels without proration
- Smoke: give the refund guard positive fixtures
- Mac: a new page 1 drops the old walk's pages, and ⌘R refreshes the list
- Billing: let a lapsed account subscribe again when nothing blocks it
- Billing: let a granted-and-subscribed account's confirming page finish
- Billing: a revoked or expired grant with no subscription reads lapsed
- Billing: cancel Stripe subscriptions before deleting an account
- Billing: react to invoice.payment_failed on WebhookReceived
- Guard against refunds from code; record step 4A
- Mac keys: one move per press, and the end measured at the press
- Fix round 1: point every plan-wording site at Plan::label()
- Mac: j, k and space in the list and the page
- Admin: show what payment could not do on /admin/users
- Mac reader: its own top air, and one gap above the summary
- Mac: Reeder's reader head, and the toolbar's Keep
- Billing: fix round 1 for /settings/billing (reviewer findings)
- Billing: /settings/billing — the Portal, Switch to Hosted, and the ladder
- Mac: a refresh with no overlap takes page 1 whole, cursor and all
- Mac: the whole library survives offline, the foreground and approval
- Mac: every item newest first, in Reeder's row shape
- Billing: fix round 1 for task 6 (reviewer findings)
- Kit: LensFilter.all, the whole library with no query item
- Reading API: a lens with no filter is the whole library
- Billing: checkout from /pending and /settings/billing (task 6)
- Mac: the tag-pill test finds the header by identifier; the app was right
- Billing: fix round 1 for the Stripe webhook (reviewer findings)
- Billing: the webhook moves standing and approves a payer
- Billing: fix round 1 for ApproveUser -- conditional update, honest flash
- Billing: ApproveUser, one approval path
- Billing: a paid Hosted account is covered and capped like a grant
- Billing: an unreadable latest invoice reads as past_due, never a 500
- Mac shared state: review fixes to labels, sign-out doc, wording and the last row
- Billing: plan, billing_state and the one function that writes them
- subscriptions.user_id must be a ULID, not a BIGINT
- Install Cashier, pin Stripe out of the suite
- Mac: Next and down-arrow tell the server the card was passed
- iOS/Mac: one AppState for both apps; MacState is gone
- Put the storage line first under Your data, and say none yet
- Show a save refusal exactly once, the plain save page included
- Say what reads the storage figure now, in config and .env.example
- Fetch no remote mail picture for an account already at its cap
- Ask MyMind for nothing at the storage cap, and clear a stale note
- Say files were left out on their own, not as an enrichment failure
- Count everything a pending account sends against its byte budget
- Count a note's or highlight's file against the storage cap
- Show a capped account how much of its storage its files use
- Import past the storage cap without the files, and count what was left out
- Write the storage cap's note before enrichment starts, as one key, in neutral words
- Save forwarded mail without its files at the storage cap, and say so on the item
- Refuse a gallery photo past the storage cap, from every source
- Refuse a capture, a Micropub photo or an uploaded PDF past the storage cap
- Make StorageQuota the storage cap, and pending's byte budget one of its answers
- Fix wave item 9 and tidies
- Fix wave item 7: a disabled five-Ws box no longer unticks a feed
- Fix wave items 1, 2 (part 2): account screen copy for month vs year exhaustion
- Fix wave item 2 (part 1): the bar follows the nearest limit, items name what ran out
- Fix wave items 4, 5, 8: tag cap counts items, fix the month-reset test
- Fix wave item 3: check the year before the month in HostedPlan::check()
- Fix wave item 6: stop logging AllowanceExhausted refusals
- Show a Hosted account its month of AI reading in words and a bar
- Disable the five-Ws box for Hosted accounts and pin their bulk exclusion
- iOS: draw the fixture picture at 3×, as the renderer did
- Mac: the waiting screen matches the phone's
- Pin Hosted accounts to Haiku 4.5 and a 24,000-character summary input
- Refuse a Hosted account's model call before it is sent, at its allowance
- HostedPlan's year check consumes AiLedger::yearStart(), not a re-derived window
- Add the Hosted plan's allowance, read off the ai_spend ledger
- Bind the admin passkey proof to its account; guard launch grants on Give
- Record the operator's AI spend on every model call
- Mac: MacState takes round five's AppState rules
- WIP: spend ledger pieces (prices, cost maths, ai_spend table, workspace tap)
- Mac: docs say the two UI defects are fixed, and what this wave found
- Mac: review minors — sidebar faces, a VoiceOver clear, one first load
- Mac: prove the keychain once before a session is built on it
- Mac: emptying the search field clears only a search lens
- Mac: a refresh or a re-deal leaves the open article open
- Mac: the reader registers with the deck
- Mac: Return in the sidebar search deals the lens; two UI tests read the Mac tree
- Mac: the back as an inspector, and the Read menu
- Mac: a link saved from the Mac says so; the text menu has one name
- Mac: the reader in the detail column
- Mac: the library window — Handpicked, the stopping point, search and lenses
- Mac: fix Sign in button to match iOS's QuietButtonStyle
- Mac: sign-in, the waiting screen, settings and the app's root
- Mac: the sidebar's model — rows, the stopping point, next and previous
- Mac: MacState — the session, the stores and the purge, without the App Group
- Mac: the AthenanaMac target, its test bundles and bin/build-mac.sh
- iOS: move the reader's page support, typography and the sign-out sentence out of the views; Theme on AppKit too
- Kit: SystemKeychain takes a service and the data-protection keychain
wyome.com
- Refresh the banked archive from the server
Sunday 27 September 2026
Athenana
- Add the free-grant screen and grant invited accounts
- Require a recent passkey for the admin area
- Keep export open for waiting and suspended accounts
- Close the operator-key leaks behind free grants
- Add athenana:storage-report and the StorageQuota measurement
- Round five low: ReaderMove keeps its own doc comment
- Round five low: a stale outbox forgets in memory only
- Round five low: count the prepared picture, and keep a 20 MB one
- Round five low: an offline deck asks again
- Round five low: ← skips cards a refresh dropped
- Round five low: count the multipart copy in the share sheet's batch
- Round five low: fill the reader template in one pass
- Round five low: stamp the outbox file with its account
- Round five low: a refused self-delete returns to /pending#delete
- Round five low: an empty pin length is thirty days, not zero
- Round five low: the total-order guard reads the direct chain as code
- Round five low: Select all on dead links reaches the rows scroll.js appends
- Round five low: refreshing the demo account ends its browser sessions
- Round five low: say truly why a waiting account's trash is not counted
- Round five low: narration cuts figures with the DOM, not a regex
- Round five low: fetch and render choose pictures by the same rule
- Round five low: the web reader parses our own asset address, never echoes it
- Round five low: a page of highlight cards loads its sources in one go
- Round five low: the cached :images reader names no host and tracks its pictures
- Item page: Move to trash beside Pin, visibility on its own line below
wyome.com
- Refresh the banked archive from the server
Saturday 26 September 2026
Athenana
- Round five: a throttled save says the server is busy, not that you're offline
- Round five: a stale page 2, or its failure, lands nowhere
- Round five: an approval check answers only for the account it started for
- Round five: a refresh keeps the card on screen when the page lands
- Round five: a main page landing in a dealt lens goes under it
- Round five: an account approved while the app runs gets its deck
- Round five: "Continue reading" works on a cold launch
- Round five: sign-out revokes the token, and the token stays on this device
- Round five: a captive portal's 200 is not a save
- Round five: a waiting account can delete itself, and its sign-out asks
- Round five: review minors — take back a failed capture's directory, and two deploy-wait notes
- Round five: DELETE /api/v1/token revokes the request's own token
- Round five: a failed file write takes back the capture API's new row
- Round five: say what the UTC migration's failed_at skip really does
- Round five: the Kindle build decides its pictures from sizes before reading any
- Round five: positions and highlight context read the pictured rendering
- Round five: the pending purge takes a denied waiting account too
- Round five: a waiting account can delete itself from /pending
- Round five: our app's one-tap screen grants only the app's own scopes
- Round five: a byte budget for a waiting account's files
- Features and compare: bring them up to date, iPhone app held back
- iOS: ready the app for App Store submission
- SEO: fit /compare and /standards in a snippet, and list three missed pages
- Privacy: say what happens to a pending account's saves
- iOS: delete what the readable-only rule made unreachable
- iOS: load only what has something to read
- Apple's cancelled return is the sign-in screen, not a 405
wyome.com
- Athenana: signing in is a passkey, a password or Apple
- Privacy: an Athenana account waiting for approval, and its saves
- Refresh the banked archive from the server
Friday 25 September 2026
Athenana
- Sign-in carries the app's request in ?next=, not only the session
- iOS: the pull line stays; Home and only readable results on a tag
- iOS: no compass; Home, pull for details, a waiting screen
- Sign-in returns to the app; pending accounts can save; a demo account
- Pin: ring the whole list row, not just its left edge
wyome.com
- Refuse three more referrer-spam hosts by name, and re-file what was already banked
- Refresh the banked archive from the server
Thursday 24 September 2026
Athenana
- Card API: a live pin is Item::isPinned(), the one predicate
- iOS UI tests: find the results, wait for the page, and wait for the reader to go
- iOS: the back asks for publish, says gone and each rung, and trash lands in place
- iOS: the reader shows its page when it is parsed, not when its pictures land
- Search: an operators-only term is dropped, and a ranked lens is always total
- Card API: visibility needs the new publish scope, not update
- IndieAuth: withdraw our app's auto-approve for a one-tap screen
- iOS: the back of a card manages it
- iOS: the next reader arrives without the chrome flashing in
- iOS: a search or a tag is a column of results
- Card API: Listen later and Send to Kindle from the back
- Card API: pin, tags and visibility from the back of a card
- iOS: Handpicked goes on as you scroll, and search shows nothing until you ask
- Lens: rank a search by title, then density
- iOS: sign in with no server field, the web's wordmark, and Sign out once
- IndieAuth: our own app skips the consent page on a first-party navigation
- Pin: bring the spec up to what was built, and hold ?view=list onto page two
- Pin: the card's edge is a ring outside the card, and the current item still wins
- Pin: a heavier ink edge on a pinned card and row, and a word for a screen reader
- Pin: the Pinned tab follows the board's layout, and isPinned() is one predicate
- iOS restyle fix wave M3: the share extension's regenerated Info.plist
- iOS restyle fix wave M3, M7 and the walk's tooling
- iOS restyle fix wave I3, M4 and the owner's four calls
- iOS restyle fix wave I2: the system tint wired, and it is accentInk
- iOS restyle fix wave I1: the pager's pages drawn back up to the screen's top, words placed by the window's inset
- iOS restyle, Task 10 step 1: the screenshot walk, committed and gated
- iOS restyle, Task 9: sign-in, the account control, the link sheet and the share sheet onto the theme
- iOS restyle, Task 7 fix round 2: "back" names the back's stack, not its scroll view
- iOS restyle: the lens list is the landing's column, with the chip
- iOS restyle, Task 7 fix round: the flip cannot wedge, the back clears the chip
- iOS restyle: the flip is a flip — CardBack behind a 3D turn, the back sheet gone
- iOS restyle, Task 6 fix round: the head clears the revealed bar, and the tint carries ink only
- iOS restyle: the reader in mymind's shape on athenana's colours, Literata by default
- iOS restyle, Task 5 fix round: the full card's text on a panel, and the stopping point said once
- iOS restyle: the full card, the lens chip, the offline line, the stop and the end onto the theme
- iOS restyle Task 4 fix round 1: lazy-fetch guard, real highlight coverage, surface/shelves rename
- iOS restyle: the landing is one column of small cards, today's deck, ending in the pause card
- iOS restyle Task 3 fix round 1: light-mode image card, top-cropped pictures, five minors
- iOS restyle: the small card in four shapes, and the pause card
- iOS restyle compass fix round 2: spec §9 gets the disabled arm, off hoisted beside dim
- iOS restyle compass fix round 1: prove the press, restore Size's rationale, four minors
- iOS restyle: the compass is the dial, chosen by the owner
- iOS restyle: two compass treatments behind -AthenanaCompass, for the owner's choice
- iOS restyle Task 1 fix round 1: accentInk, Literata-Regular, readerTitle, a scoped share appex
- iOS restyle: the theme, athenana's tokens dark-first, and the three faces bundled
- Pin: write down the expiring-pin swap, and bring the spec up to what was built
- Smoke: read every return the method makes, and drop arrow-function bodies
- Pin: Keep another N days on a live pin, and list every status on the tab
- Pin: scan the deck and the share for a pin, and say who unpin can strand
- Pin: hold the two exclusions shut, and write down what it costs the phone
- Pin: Unpin from the Pinned tab goes back to the tab
- Pin: from=pinned, so j and k walk the tab rather than the board
- Pin: the total-order guard reads what a method returns, as code
- Pin: a Pinned tab between Revisit and Dead links, listing live pins
- Pin: two routes and the control in the item page's action row
- Pin: unpinning stays immediate, and tomorrow's draw is the whole pool
- Pin: a pin made today takes effect tomorrow, like an open
- Pin: a pinned item is not due for resurfacing
- Pin: the column, the setting and the one safe write
- Run the MySQL session in UTC, and convert every TIMESTAMP to match
Wednesday 23 September 2026
Athenana
- Reading API test walks: fail at fifty pages instead of hanging
Tuesday 22 September 2026
WyHealth
- Stop host-gate failing on a port nobody dialled
wyome.com
- Refresh the banked archive from the server
Hosting monitor
- Bless matomo-spammers.txt in the referers directory
- Put the by-hand commands on the page itself
Monday 21 September 2026
Athenana
- Dead links tests: guest DELETE is refused, and the frozen clock always resets
- Dead links: correct the trash-as-items._row claim, the button's own name, and two understated docs
- Dead links: record the two things left out, and the measured row at 375 and 1024px
- Dead links: tick rows and move them to the trash from a sticky bar
- Item row: build the optional checkbox as a string so an absent form adds zero bytes, and freeze the byte-identity test's clock
- Item row: an optional checkbox joined to a bulk form by id, byte-identical for every caller that passes none
- Revisit dead links: eager-load tags and assets, like every other items._row caller
- Revisit: a Dead links tab listing every link whose page answered 404 or 410
- Surface: the Handpicked shelf offers only readable cards
- Revisit: carry the draw through the reader, so Next still walks the set after "Read this article"
- Share sheet: an ordinary page declares no PDF, so a declared PDF the sheet cannot read refuses the whole share
- Share sheet PDF fix wave: the url rule's real reason, our sentence first for a non-PDF, and the small corrections
- The share sheet reads a PDF first and refuses in words what it cannot: a second one, one over 15 MB, a file of another kind
- A PDF is a CaptureInput: the payload posts it as a document, the sheet parks and names it like a picture
- Make creatableOverApi() an explicit allowlist again, so a new ItemType is not creatable over the API for free
- Let the capture API take a PDF as a document, holding the no-file line in the rules rather than the type list
- Move the PDF upload rules into one class the save form and the API will share
Sunday 20 September 2026
Athenana
- iOS home: the Surface is the root with a Handpicked shelf, the deck pushed over it, one reader cover on the stack
- iOS deck store: the deck is entered from the Surface and left for it — enter(_:), leave(), a launch that opens nothing
- build-ios.sh: key the log directory on the checkout like DerivedData, so two worktrees never share a test.log
- Share sheet: short text beside a link is a caption, and the share is the link
- iOS reader: the title and the description head the page, above the article
- iOS reader: clamp the sideways reads, or a rubber-band refuses every swipe
- iOS reader: a sideways scroll or a second finger is not a swipe; the docs the branch owed
- iOS reader: one cover with its screen swapped inside it, and the chrome pinned while the page loads
- iOS UI test: a flick up at the end of a short article is ↑ now, so the reader test scrolls with a short drag
- iOS reader: the page's pictures, asked for with images=1 and answered from the app's own picture path
- iOS reader: the compass's four moves are gestures on the page — a swipe is → and ←, a pull past an edge is ↓ and ↑
- iOS pictures: a 5xx or a cut stream retries once and is then forgotten, never remembered for the session
- iOS deck: the reader is a readable card's default face, and the card is the flip-back
- iOS reader: with no page, the chrome is on screen and stays, so Back to card is there
- iOS app icon, from the same icon.svg as the web's, flattened opaque
- iOS compass: a 120pt disc, down from 156, at the owner's request
- iOS reader: a server refusal says "Nothing to read on this page", never "Not saved for offline"
- Reader: a link under the reader's floor is not readable on the card, and a <picture>'s image is shown
- Send to Kindle: pack the article's own pictures into the EPUB, and drop them largest-first under the ceiling
- API reader: images=1 emits a page's stored pictures at absolute API asset addresses
- Narration: cut every figure before the text goes to the voice, so a caption is never spoken
- athenana:backfill-article-images: run the image stage alone over the links archived before it existed
- A/B fix wave review: name every type in isReadable(), refuse a non-web URL before decoding a picture, pin the shelf's rule
- iOS surface: the search field under the title, where iOS 26 had put it in the bottom toolbar
- iOS capture: Cancel during a slow resolve, a batch byte ceiling, one scheme rule for the intent
- iOS reader and deck: the back's rules on the store, a quote that finds its block, a scheme that repaints
- iOS Kit and AppState: a keychain delete that reports, a purge that waits, a picture cache that empties
- iOS: a caption needs a path, and a readable shelf card opens the reader at once
- Reading API tidy: ShareStatus enum, the guards' tokenizer stripper, and the tests the build deferred
- Deck: the last full page carries no cursor, the switches are read once a deal, and one base query for the lens, the surface and the ingredients
- Reading API: one readable predicate on Item, one archive read per reader request, and a remembered miss
- Build both appexes without Xcode 27's debug dylib, since a device never registers a stub extension
- iOS capture: record the fix wave's three Swift traps, trim the outbox's forgotten set to the file, and tolerate spaces in an entitlements plist
- iOS capture fix wave, Swift minors: one ladder for the link sheet, a merged outbox move, sized refusals, Debug-only strings
- iOS capture spec and docs: the built handler contract, §10 as the ledger, the measured counts
- iOS capture fix wave: sweep dot-files out of the staged appex, drop the unread fromNativeHost, pin the fourth client and CORS credentials
- Share sheet: re-encode a HEIC through the one ServerImage rule the intent already used
- build-ios.sh --extensions: match each group under its own entitlements key, and read the closure off the stager
- Outbox: an id this instance removed is never read back off a file whose rewrite failed
- iOS capture: pin the three clients' field sets on the server, and record what the build learned
- Safari staging: rewrite the manifest with /usr/bin/python3, since an Xcode script phase has no node on its PATH
- Safari extension on iPhone: the existing extension, staged by the Mac build's rule, with the app's session answered by a native handler
- UI test: retry the article-link tap, since the reader's position restore moves the link under it
- Extension: only a session-shaped reply is a native host's answer, so an echoing handler cannot read as a signed-out phone
- Extension: take the session from a native host when there is one, so the iPhone build needs no pasted token
- App Intents fix round: a HEIC is re-encoded as JPEG since IntentFile will not, and Continue reading opens the article on a warm app too
- iOS app: Save to Athenana and Continue reading as App Intents, so Shortcuts and Siri keep their composability
- Outbox: a purge re-reads the file first, so a picture the extension parked goes with it
- UI test: wait for the surface's single card to settle before tapping it
- Outbox: re-read outbox.json before every read and write, so the share extension's entries survive the app's next save
- iOS share extension: share → saved → done, with a note one tap away and an outbox for the plane
- iOS app: an App Group for the outbox and a Keychain access group for the token, ahead of the extensions
- CapturePayload: key an image on its bytes, not its name; a caption's trailing slash still marks the link
- AthenanaKit: one payload for every capture, a multipart save, and an outbox entry that carries a file
wyome.com
- Refresh the banked archive from the server
- Make the reclassify() archive write atomic like the harvest write already is
- Classify the two spam families in the generator too, and re-file what was already banked
- Say that Athenana's reader now shows an item's pictures, from copies on its own server
- Restore "no hidden image" on the weekly-email promise
- Promise that no image in the weekly email reports an open, not only no hidden one
Saturday 19 September 2026
Athenana
- Drop a forwarded newsletter's unsubscribe footer from the reader
- Bring the reader's own tests onto the new picture rule, and stop "kept" meaning two things
- Move the worker's --timeout with the budget FetchArticleImages raised
- Reader: stop running blocks together, drop page furniture, and show an article's pictures again
wyome.com
- Refresh the banked archive from the server
- Say what the 403 double fault actually cost: refusals logged as 500
- Serve Apache's own 403 page on the other three docroots too
- Serve Apache's own 403 page to a refused request
- Name both candidate paths in the missing-spam-list warning, and fix two facts
- Test the Matomo wiring with a host that is not also in SPAM_HOSTS
- Filter the Matomo referrer-spam list on the statistics page
- Carry the referrer-spam block on the other three docroots
- Refuse a request whose Referer names a known spam family
- Record a referral only on a 200 or 304, so a refused request never reaches the page
- Refresh the banked archive from the server
Wednesday 16 September 2026
Athenana
- CSP: let the IndieAuth consent form redirect to the native apps' scheme
- iOS app review fixes: pictures over the API with a bearer, a 304 keeps the reader's block, snapshots respect the purge, notes through ReadableHtml, and a lens keeps the way back
- iOS app: a purged outbox takes nothing and the open reader flushes first; a failed refresh keeps the deck paging and spends no window
- iOS app: offline deck and outbox replay on foreground, sign-out that purges, a release script, screenshots, and the record
- iOS app: the back flipped over the surface's reader has Open original; a list jump pages; a dead state dropped
- iOS app: the card back with share-out, lenses with their list and chip, and the surface with search
- iOS reader: a flushed position names its rendering, so reopening the card resumes; the trailing report is the latest build's
- Reading API and iOS reader: a card's position names its rendering, and the reader opens at the block only for that rendering
- iOS reader: the article in a WebView, a block-indexed position through the outbox, tap-to-reveal chrome, Keep, the link sheet, typography per device
- iOS app: Next mutates before it awaits, history is ids, and a refused token signs out with the full purge
- iOS app: a swipe is Next and Back — it passes and remembers the card, as the compass does
- iOS app: sign in, the deck and its compass, cards by type, and the stopping-point card
- iOS reader: exclude the reparented <script> from position tracking, and clean up the postbuild strip
- iOS reader: the page template and a script that reports the block index, tested with Node
- AthenanaKit: the outbox and the article cache survive a purge or a newer position landing while a request is in flight, and a drop is reported
- AthenanaKit: an article cache that revalidates by ETag, and an outbox that replays in order and keeps a position's own clock
- AthenanaKit: pin the session's departures from the brief, and refuse a callback from another issuer
- AthenanaKit: the session — PKCE, the IndieAuth flow that refuses a foreign state, and a token that lives only in the Keychain
- AthenanaKit: models and a client for every reading endpoint, with fixtures the PHP suite holds to the presenter
- iOS app: a generated Xcode project, the AthenanaKit package, and a build script that reads xcodebuild's own status
- Reading API: a note reads from its body, and an image card carries the full picture
- Newsletter review follow-ups: aspect-ratio note, access-log clause, comment reword
- Newsletter view polish: one issue date, block @php, text escaping, lowercase wordmark, bulletproof Read pill
- Send CORS on the woff2 fonts so Apple Mail renders them
- Harden the newsletter body-identical guards against a smuggled value
- Record what the weekly email fetches, and why that is the promise now
- Say on the privacy page what the weekly email now fetches, and hold the view to it
- Set the weekly issue in the app's own typefaces, served from this host
- Show each emailed link's preview picture, through the public route, and pin that every reader gets one body
- Fix two newsletter tests that were silently asserting nothing
- Send the weekly issue as a designed page, with a text part beside it
wyome.com
- Say what the weekly email now fetches: pictures and a typeface, the same for every reader
- Refresh the banked archive from the server
Tuesday 15 September 2026
Athenana
- Reading API review fixes: positions in UTC and on every card, a bad host lens is refused, and four tidy-ups
- Reading API review fix: one position per item, the search test fails rather than passes under a transaction, and only the card back's own echo of visibility is exempt from the principle-6 guard
- Reading API: prune passes nightly, hold principle 6 with a test, and record what the build learned
- Deck settings: the switches, over the API and on a web screen
- IndieAuth: our own apps as a client, returning to a custom scheme the client page lists
- Reading API review fix: the card back gates Rec League behind the same switches as its share list
- Reading API: the card back, share-out through one action both controllers call, and a share scope
- Reading API: keep a passage over the API, and bind every highlight to its source item
- Reading API review fix: the resurfaced shelf resolves switches in one query, not one per item
- Reading API: the surface's two shelves, and one lens for tag, host and search
- Reading API review fix: a tampered cursor is a 422 and not a 500, base64url for the iOS client, and a walk never re-deals what became in-progress after it began
- Reading API review fix: a highlight in progress is dealt once, at the front; a switch off removes an in-progress item too
- Reading API: deal the deck — in-progress first, then the operator's pattern over seeded ingredients
- Reading API review fix: read items.host instead of re-deriving it, make both upserts race-safe, and cover ReadingCard
- Reading API: the card, a block-indexed position that the older device cannot overwrite, and passes
- Reading API review fix: drop the scope by name in RecordOpen, and two unused test imports
- Reading API: the reader as blocks, with a hash and an ETag, and the open recorded
- Deck switches: what a person may leave out, and the operator's defaults
- Reading API: positions, passes, a highlight's source item, and per-user deck switches
WyHealth
- Read a silent probe as no answer, not as absence
Hosting monitor
- Stop not-served and dir-listing passing on a server nobody reached
- Say the Mac was offline instead of rendering eight sites down
Monday 14 September 2026
Athenana
- Run the feed cards the full column, the width the board's list view has
- Select every tag on the manage-tags page with one press, and clear them with the next
Sunday 13 September 2026
Athenana
- Prune a fetched feed with no entries whatever its age, and name each feed the prune takes
- Raise the narration ceiling to 60,000 characters, and count the saved text on the item page
- Keep a Day One entry whose URL line is longer than the save form allows as a note
- Hand the Reeder job test the Day One action too, and untangle the format tests after the rebase
- Bound the Day One decode and the text columns from the bytes, and anchor the guards
- Name Day One on the import screen, and count its photos and skipped entries
- Ask the zip for its journal before reading the upload, and bound the rest by size on disk
- Route a Day One export through the import job, zip open for its photos
- Own the Day One test zips, and say nothing per entry when there is no zip
- Put a Day One entry's photos in the note's gallery, the first as its card picture
- Say what keeps a binned Day One entry binned, bound the uuid, count tags as the vocabulary does
- Import a Day One entry as a private note, or a private link when it is a share-sheet save
- Refuse a URL line that carries prose, and read a CRLF body the same as LF
- Read a Day One entry's text: the escapes, the share-sheet shape, the note body
- Read the journal JSON out of a Day One zip, in place
- Detect a Day One JSON export
- Bound the import upload by an archive ceiling of its own
- Run athenana:prune-feeds daily at 03:30
- Forget feeds silent for a year: athenana:prune-feeds
- Make the feeds page a list scroll.js extends fifty rows at a time
- Move the Share panel under the saved page text
- Drop the fill from the item page's Share panel; it keeps its outline
- Put Previous / Next and Back on one row: the nav on the left, Back on the right
- Put Read / Listen on the tags' own row, right-aligned; the chips wrap beside them
- Move the add-a-tag field under the Title and note form; the chips stay under the title
- Reorder the item page: title, tags, Read/Listen right-aligned, picture, share, labelled text
- Call the first two tabs In and Out, under the Import / Share heading
- Make site: search the saved URL's domain, and count a feed's saves the same way
- Head the four sharing tabs "Import / Share", to match their sidebar row
- Label the settings sidebar's Sharing row "Import / Share"
- Walk a source from inside an item: Next and Previous stay on the source you came from
- Tidy the source board after review: honest host test, no tag-timeline link on a source strip, prefixed helpers
- Link the source named on an item page to everything saved from that domain
- Draw a source's history above its board, against every save as the baseline
- List every item from one source domain at /from/{host}, on the tag board's template
- Record each item's source host, written on save and backfilled from the URL
- Define the source domain of a URL once, in PHP
- Correct what the branch review found overstated or understated in the Reeder import's comments, copy and spec
- Charge scalars in the JSON Feed decode estimate, and stop truncating an untitled long url into a permanent title
- Detect a JSON Feed export whose slashes are escaped, as Reeder writes them
- Name Reeder wherever the import formats are listed, and import both files end to end
- Detect a Reeder export, either shape, and hand it to its parser
- Read a JSON Feed file as private links tagged with the feed's name
- Bound a Reeder export's containers at three a link, which is what the shape costs
- Read a Reeder Classic Read Later export as private, tagged, untitled links
- Record in the backlog that the narrowed-board walk plucks the whole list
- Walk a search from inside an item too, and make the narrowed board one context
- Walk a tag from inside an item: Next and Previous stay in the tag you came from
- Say what the JSON decode estimate cannot see, rather than claiming it never under-counts
- Tidy the JSON Feed branch after review
- Say on the standards page that JSON Feed is read as well as published, and anchor it
- Never throw out of a JSON feed's date
- Measure a JSON body before decoding it, and decode it in one place
- Read a JSON Feed wherever a feed body is parsed, and record json as its kind
- Read past a byte-order mark when deciding which feed parser to use
- Dispatch a feed body to the JSON or XML parser on its first byte
- Parse JSON Feed 1.1 into the shape the feed pipeline already reads
- Pick the axis's label density from the pixels it has, in both directions
- Say on the privacy and features pages what a file import does, and hold both policies to it
- Label a long axis by a stride of years, so a twenty-year library reads
- Thin a tag axis past four years to its Januarys, and give the first tick its room
- Bound a Pinboard JSON backup's element count by its commas before decoding
- Run the retry backfill's tests as an administrator, now the command is gated
- Name Pinboard where the import formats are listed, and make two fixtures honest
- Count a Pinboard JSON backup's entries before decoding it
- Hold both backfills to the same key gate as enrich-pending
- Say what the Sharing In link means for the phone gap, and make the keyless copy test discriminate
- Move the import onto Sharing In and 301 the old address
- Read an import's pages only for an account that pays for it
- Import a Pinboard bookmark that was not shared as private
- Detect a Pinboard XML or JSON backup and hand it to its parser
- Read a Pinboard XML backup
- Read a Pinboard JSON backup
- Say on both public pages that the Share block can be switched off
- Exercise forget on a still-hidden target
- Show a switched-off share refusal outside the panel the switch removes
- Put a switch on every share target and a master switch above them
- Add the sharing-out switch and per-target hide and show actions
- Refuse a share to a hidden target, or any share with sharing out off
- Make the listing share-icon negations actually discriminate
- Fix User::sharesOut() to default true for an unrefreshed model
- Honour the sharing-out switch and the hidden list in the one share-target gate
- Give an account a sharing-out switch and a list of hidden share targets
- Wash the trash's thumbnails like the board row's
- Show each trashed item its listing picture, and serve it
- Make a feed due a day less the run's length, so no feed skips a night
- Name every trashed item: one list-title rule for the row and the trash
wyome.com
- Name Reeder among the file imports on the privacy page, beside Athenana's
- Say JSON Feed can be followed from Athenana
- Say what a bookmarks-file import into Athenana does with the file
- Refresh the banked archive from the server
Saturday 12 September 2026
Athenana
- Tighten the posting targets after the branch review
- Stop /shares calling micro.blog the one target that posts
- Keep a rejected share token out of old input
- Say on the privacy page that Share sends MyMind a link, beside the import's promise
- Refuse a redirect on every posting share request, so a user-typed host cannot bounce this server
- Record the competitor share targets as built
- Hold both privacy pages to naming the four bookmarking apps
- Name the five targets the server checks on connect, since MyMind is not one of them
- Say on the privacy page which of eleven share targets the server posts to, and guard all seven
- Reframe the /shares stance as no lock-in and list the five bookmarking apps
- Draw a mark for each bookmarking-app share target
- Share a saved link back to MyMind through the import key
- Require a real host in a Karakeep address, with no query string or sign-in
- Share a saved link to a self-hosted Karakeep
- Share a saved link to Readwise Reader
- Share a saved link to Raindrop
- Name every posting endpoint in the parity guard so a new target file counts as a poster
- Share a saved link to Pinboard
- Add the four bookmarking-app credentials and the Karakeep address to users
- Connect and forget any posting target from its declared fields
- Draw posting share targets from the registry rather than a block each
- Move Are.na onto the shared posting controller
- Move the posting-share ladder into one controller, with micro.blog as its first target
- Keep every item-page form inside the Revisit draw it was opened from
- Size the Send to Device headings like the other tabs
- Key the Send to Device section rhythm on its two ids, not on every section
- Restore the column rhythm inside the Send to Device sections and fix the tab strip's overflow
- Count the Send to Device POSTs correctly: six, not five or seven
- Replace five settings rows with one Sharing row
- Put the Sharing tab strip on its four pages
- Put Podcast and Kindle on one Send to Device page
- Give the five-Ws pass five minutes by default, not two
- Close the five-Ws review: skip headline-only stories, echo the ceiling on the privacy page, pin the third nonce
- Say on the privacy page that ticked feeds' stories are summarised, and the article fetched when the feed gives a line
- Show the five Ws of the ticked feeds' stories under the briefing on Discover
- Run the five-Ws step inside the discovery build, and prune its rows with the rest of the morning
- Write a story's five Ws from the feed's summary, or from the article when the summary is a line
- Name the five-Ws article fixture apart from FullChainTest's
- Ask Claude for a story's five Ws, and let FeedSource narrow the window to what still owes one
- Extract the article-text read from ExtractContent into ReadableText
- Add the feed_summaries table and its three ceilings
- Toggle a feed's daily five-Ws summary from its card
- Let a feed be marked for a daily five-Ws summary when it is added
- Send the item's picture with an Are.na share instead of letting Are.na screenshot the page
- Stop the privacy page promising nothing goes to third parties
- Anchor wyome's WyHealth logging promise to WyHealth's code, with a skip for an absent checkout
- Say the Kindle send carries your note and can be downloaded; re-read the chart's row
- Rank the artist's own channel above a nearer stranger
- Name what the privacy page had missed: federation, MyMind, IndieAuth, the host
- Match a song on its title as well as its length, and read a single off its page
- Name the six share targets on the privacy page, and hold the promise to the code
- Say the download is a rebuild, and match the small print to the box
- Say that the note goes to the Kindle only if you tick the box
- Offer the note, and refuse a second press
- Let the file be downloaded once it has been sent
- Strip <img> from the Kindle note, in the DOM
- Build the Kindle file in one place, and let a send carry the note
wyome.com
- Name the five bookmarking apps a saved link can be shared to
- Say that an Are.na share carries the item's picture, never a screenshot
- Refresh the banked archive from the server
- Say the stylesheet serves every page, not three
- Name WyHealth in the three page descriptions that still listed four apps
- Say where WyHealth's data lives and what the app sends; drop the flows it does not yet have
- Refresh the banked archive
- Drop bot and redirect-follower referrals from the statistics page
- Say what Athenana's blog delivers to followers, and name MyMind, IndieAuth and the host
- Name the six places a saved link can be shared to
- Say that a Kindle send carries your note only if you ask
Friday 11 September 2026
Athenana
- Make a cover-shaped cover from a page's picture
- Give the EPUB a place for the reader's own note
- Hold wyome.com/privacy to the Send to Kindle promise as well
- Keep the Kindle address out of laravel.log and failed_jobs
- Say that Send to Kindle mails an article to Amazon, and hold it to the code
WyHealth
- Take Next 16.3.4 for the AVIF image-optimizer RCE
wyome.com
- Refresh the banked archive from the server
- Say that a saved article can be sent to a Kindle
Hosting monitor
- Bless standards/ in the wyome.com docroot
Thursday 10 September 2026
Athenana
- Downgrade three Send to Kindle cells from no to unknown
- Say in public that an article can be sent to a Kindle
- Let the Kindle refusal show for the two cases that could never see it
- Put Send to Kindle on the reader, and say what the last send did
- Record a Kindle send the catch never saw, and test the passages stay the owner's
- Mail an item to a Kindle, and write down what happened
- Keep a Kindle address on the account, refused unless it is Amazon's
- Fail loudly on a bad EPUB write instead of shipping empty bytes
- Build an EPUB from the reader's output, as a pure function
- Take the "no other bookmarking apps" block off the shares page
- Say on the privacy page that a PDF attachment is kept, and guard the claim
- Say what a document is on the board card and the list row
- Tell every cache not to keep a document
- Close four things a review of the branch found
- Draw page one with poppler, not ghostscript
- Save a PDF attached to a forwarded message as a document of its own
- Show a document on its own page, and give the board the right picture
- Run the extraction, and serve a document as a download
- Let a PDF be uploaded from the form that already saves everything else
- Point the new tests at tests/fixtures, which is its real name
- Read a PDF into the column search already reads
- Share the link, never the note — and write down the inbound account wall
- Refuse a double-clicked share, and stop listings privileging one service
- Stop the documented URL running over the column beside it
wyome.com
- Say that a PDF attached to a forwarded message is kept
Built 2026-10-09 06:00 from the last 30 days of git history. This page is rebuilt daily from a laptop, so if that date is old, the laptop was off — not the projects.