Secrets are stripped first
Diffs pass through a secret scanner before any model call. Files that look like credentials are removed rather than summarised, so a key committed by accident does not become training input or a draft.
Deployable reads your merged pull requests and drafts the thread, the LinkedIn post, and the changelog entry.
Three surfaces from one pull request, each rendered from the same set of extracted facts so they cannot contradict each other. The drafts below were written by hand to show the format while the live corpus is being generated. The pull requests are real, and every claim carries the file it came from.
fix(etag): resolve incorrect incremental hashing for chunked responses
If you served streamed responses through Hono's ETag middleware, two different bodies could end up with the same ETag. That is fixed.
The middleware was hashing the first chunk and treating it as the whole body. Anything that differed only after the first chunk hashed identically.
src/middleware/etag/index.tsHashing is now incremental across every chunk, and the digest is finalised when the stream closes.
src/middleware/etag/index.tsThe practical effect: a conditional request against a body that actually changed now misses the cache instead of getting a stale 304.
src/middleware/etag/index.test.tsA subtle caching bug in Hono, now fixed. The ETag middleware hashed only the first chunk of a streamed response and treated that digest as the whole body. Two responses that differed only after the first chunk would produce the same ETag, and a client holding the old copy would get a 304 for content that had changed. Hashing now runs incrementally across every chunk and finalises when the stream closes. If you stream responses and rely on ETags, this is worth picking up.
## ETags are now correct for chunked responses - The ETag middleware hashed only the first chunk of a streamed response, so two different bodies could share an ETag. - Hashing now runs incrementally across every chunk, and the digest is finalised once the stream closes. - A conditional request against a changed streamed body now correctly misses the cache instead of returning 304.
feat: adaptive progressive image loading for photo viewer
Opening a photo in Immich no longer means staring at an empty frame. The picture shows up right away and sharpens as it loads.
Before this, the viewer waited for the full-resolution file before drawing anything at all. On a slow connection that was a second or two of blank space, on every photo.
web/src/lib/components/asset-viewer/photo-viewer.svelteNow a small preview appears immediately and gets replaced as the real image arrives, so there is always something to look at.
web/src/lib/components/asset-viewer/photo-viewer.svelteThe preview size adapts to your connection as well, so a slow network is not sent a large file it has no chance of loading quickly.
web/src/lib/utils/asset-utils.tsA small change, and the kind you feel every single time you use the app. Opening a photo in Immich used to wait for the full-resolution file before drawing anything. On a slower connection that meant a blank frame for a second or two, on every photo you opened, which is the sort of thing people experience as "this app is slow" without being able to say why. The viewer now shows a small preview immediately and sharpens it as the full image arrives. It also picks the preview size based on your connection, so a slow network is not handed a file it cannot download quickly. Perceived speed is mostly about whether something appears, not about how long the whole thing takes.
## Photos now appear the moment you open them - The viewer used to wait for the full-resolution file before drawing anything, so a slow connection meant a blank frame on every photo you opened. - A small preview now renders straight away and is replaced as the full image arrives, so there is always something on screen. - The preview size is chosen from your current connection speed, so a slow network is not handed a large file it cannot download quickly.
Validate content collection reference() IDs after sync
Astro content collections now catch broken reference() IDs at sync time instead of letting them fail during render.
Before, a reference pointing at an entry that did not exist passed sync happily. You found out when a page blew up, often on a route you were not editing.
packages/astro/src/content/sync.tsReference IDs are now validated against the target collection while syncing, so a typo fails right away and names both the id and the collection.
packages/astro/src/content/sync.tsThe error also names the file the bad reference came from, which removes the part where you grep the content tree to find it.
packages/astro/src/content/errors.tsAstro shipped a small change to content collections that removes a genuinely annoying debugging loop. A reference() pointing at a nonexistent entry used to pass the sync step and only fail at render time, often on a route unrelated to the one you were editing. The stack trace pointed at the renderer rather than the content file. Reference IDs are now validated during sync. A typo fails immediately, and the error names the id, the collection, and the file the reference came from. Shorter feedback loops are most of what good DX is.
## Broken collection references now fail at sync, not at render - A reference() pointing at an entry that does not exist used to pass sync and only surface as an error when the page rendered. - Reference IDs are now checked against the target collection during sync, so a typo fails immediately with the offending id and collection named. - The error names the file the bad reference came from, so you are not searching the content tree for it.
fix(client): serialize multiple cookies correctly
Hono's client was dropping cookies. If you set more than one, only the last survived the request.
They were being collapsed into a single header value rather than serialised as separate pairs, so a session cookie plus anything else meant the session cookie lost.
src/client/utils.tsSerialisation is fixed, and every cookie you set now arrives. Worth updating if you use the client with authenticated requests.
src/client/utils.tsA small fix in Hono with an outsized failure mode. The client collapsed multiple cookies into a single header value, so only the last one set actually made it into the request. If you set a session cookie and then a preference cookie, authentication quietly broke, in a way that looks like a server problem rather than a client one. Cookies are now serialised as separate pairs and all of them arrive. The bugs worth writing about are usually the ones that fail silently in the wrong direction.
## The client now sends every cookie, not just the last one - Multiple cookies were collapsed into a single header value, so only the last one survived the request. - Cookies are now serialised as separate pairs joined correctly, so a session cookie and a preference cookie both arrive.
The engine pulls a set of facts out of the diff, and each fact carries a citation to the hunk that proves it. Every surface is then rendered from that same fact set. A faithfulness pass removes any claim it cannot trace back to the code, and tells you how many it removed.
Draftpending your review
A single bad message used to take down an entire queue batch. Now each message retries on its own, and only a fully failed batch escalates.
Messages that exhaust their retries land in a dead letter queue rather than disappearing, so nothing is lost while you debug.
src/queue/consumer.tsDiffs pass through a secret scanner before any model call. Files that look like credentials are removed rather than summarised, so a key committed by accident does not become training input or a draft.
Every generated claim is checked against a cited hunk. Claims that fail are dropped outright rather than softened, and the draft reports the count, so a quiet failure is visible instead of invisible.
The pipeline pauses on a durable approval step that can hold for two weeks. Nothing reaches a timeline, a feed or a changelog until you approve it. This is a workflow with known steps rather than an agent with latitude, which is the reason the pause is reliable.
A dependency bump, a flaky test fixed, an edge case handled. Individually none of it is worth a post, so it goes unwritten. Once a week Deployable collects what nobody would publish on its own and writes it as one piece of narrative, which is the part that changelog generators structurally cannot do.
Weekly rollupone draft
Quiet week on the surface, busy underneath. Queue handling got noticeably more forgiving: an empty batch no longer trips the consumer, and a zero-length hunk no longer throws during diff sizing. Lockfiles are now skipped when measuring diff size, which is the change most people will actually feel, because it stops a dependency bump from looking like a thousand-line pull request.
Git-native changelog tooling already exists and most of it is free. If a bullet list of merged pull requests is what you need, use one of these instead. The difference is what happens after the changelog.
| Capability | GitHub release notes | release-please | Changelog CMS | Deployable |
|---|---|---|---|---|
| Produces a changelog | Yes | Yes | By hand | Yes |
| Reads the diff | No | No | No | Yes |
| Writes in your voice | No | No | No | Yes |
| Thread and LinkedIn post | No | No | No | Yes |
| Weekly narrative rollup | No | No | No | Yes |
| Cites the code behind a claim | Links the PR | Links the PR | No | Cites the hunk |
Point us at a public repository. We run its recent merged pull requests through the engine and send back what it wrote, citations attached, so you can judge the output before installing anything.
Free
A capped number of content pieces each month, including at least one weekly rollup, so the part that makes this different is not behind the paywall. Carries a footer credit.
Solo
$39/mo
One product, private repositories, every surface, generous volume.
Team
$99/mo
Several products, higher volume, multiple reviewers, no footer credit.
Billing is not self-serve yet. Pricing is listed so you can decide whether this is worth your time before you talk to anyone.