<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:dw="https://www.dreamwidth.org">
  <id>tag:dreamwidth.org,2008-06-03:11</id>
  <title>Dreamwidth Changelog</title>
  <subtitle>Dreamwidth Changelog</subtitle>
  <author>
    <name>Dreamwidth Changelog</name>
  </author>
  <link rel="alternate" type="text/html" href="https://changelog.dreamwidth.org/"/>
  <link rel="self" type="text/xml" href="https://changelog.dreamwidth.org/data/atom"/>
  <updated>2026-04-24T03:09:22Z</updated>
  <dw:journal username="changelog" type="community"/>
  <entry>
    <id>tag:dreamwidth.org,2008-06-03:11:1928515</id>
    <author>
      <name>github</name>
    </author>
    <dw:poster user="github"/>
    <link rel="alternate" type="text/html" href="https://changelog.dreamwidth.org/1928515.html"/>
    <link rel="self" type="text/xml" href="https://changelog.dreamwidth.org/data/atom/?itemid=1928515"/>
    <title>[dreamwidth/dreamwidth] d0f4a9: devcontainer: install Manticore and tighten .docke...</title>
    <published>2026-04-24T03:09:22Z</published>
    <updated>2026-04-24T03:09:22Z</updated>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='github' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://github.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://github.dreamwidth.org/'&gt;&lt;b&gt;github&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Branch: refs/heads/main
  Home:   https://github.com/dreamwidth/dreamwidth
  Commit: d0f4a97384fd81eef7ce77dd92157eef6e473d34
      https://github.com/dreamwidth/dreamwidth/commit/d0f4a97384fd81eef7ce77dd92157eef6e473d34
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;m&amp;#x61;&amp;#114;k&amp;#64;&amp;#x64;&amp;#114;&amp;#101;&amp;#x61;&amp;#109;&amp;#x77;&amp;#x69;&amp;#100;&amp;#x74;&amp;#x68;&amp;#46;&amp;#111;&amp;#114;&amp;#x67;&lt;/a&gt;
  Date:   2026-04-23 (Thu, 23 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M .devcontainer/Dockerfile
    M .devcontainer/config/etc/dw-etc/config-local.pl
    M .dockerignore
    M etc/config-local.pl.example&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;devcontainer: install Manticore and tighten .dockerignore&lt;/p&gt;

&lt;p&gt;Manticore Search is installed but not auto-started, so developers who
don't touch search pay no runtime cost. Enable with a commented
&lt;span style='white-space: nowrap;'&gt;&lt;a href='https://www.dreamwidth.org/profile?user=lj'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://www.dreamwidth.org/profile?user=lj'&gt;&lt;b&gt;lj&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;::MANTICORE line in config-local.pl plus &lt;code&gt;searchd --config
/etc/manticoresearch/manticore.conf&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;.dockerignore now mirrors .gitignore so &lt;code&gt;docker build .&lt;/code&gt; is hermetic on
dev hosts with local state (extlib, build, ext/local, node_modules, etc.);
CI checkouts were already clean.&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.7 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;&amp;#x6E;&amp;#x6F;&amp;#114;&amp;#x65;&amp;#112;&amp;#x6C;y&amp;#64;&amp;#97;&amp;#110;t&amp;#104;&amp;#114;&amp;#x6F;&amp;#112;&amp;#105;&amp;#99;&amp;#x2E;&amp;#x63;&amp;#111;&amp;#109;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Commit: 8faae76d08f5ff7e152dfb5084d28257f996fd08
      https://github.com/dreamwidth/dreamwidth/commit/8faae76d08f5ff7e152dfb5084d28257f996fd08
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;&amp;#x6D;&amp;#97;rk&amp;#64;&amp;#100;&amp;#114;&amp;#x65;&amp;#x61;&amp;#x6D;&amp;#x77;&amp;#x69;&amp;#x64;&amp;#x74;&amp;#x68;&amp;#x2E;&amp;#x6F;&amp;#x72;&amp;#x67;&lt;/a&gt;
  Date:   2026-04-23 (Thu, 23 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M bin/worker/sphinx-copier
    M cgi-bin/DW/Controller/Search/Journal.pm
    M cgi-bin/DW/Controller/Support/Search.pm
    A cgi-bin/DW/Search.pm
    M cgi-bin/DW/Task/SphinxCopier.pm
    R t/search-manticore.t
    A t/search.t&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Add DW::Search: unify Manticore and Sphinx behind one module&lt;/p&gt;

&lt;p&gt;Controllers now call DW::Search::{search_journal,search_support}
directly; the Gearman/Storable dispatch lives inside the module.
&lt;span style='white-space: nowrap;'&gt;&lt;a href='https://www.dreamwidth.org/profile?user=lj'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://www.dreamwidth.org/profile?user=lj'&gt;&lt;b&gt;lj&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;::MANTICORE picks the synchronous SphinxQL path, &lt;span style='white-space: nowrap;'&gt;&lt;a href='https://www.dreamwidth.org/profile?user=lj'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://www.dreamwidth.org/profile?user=lj'&gt;&lt;b&gt;lj&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;::SPHINX_SEARCHD
falls through to the legacy Gearman worker, and templates see the same
result shape either way.&lt;/p&gt;

&lt;p&gt;Both copier paths fan out to SearchCopier when &lt;span style='white-space: nowrap;'&gt;&lt;a href='https://www.dreamwidth.org/profile?user=lj'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://www.dreamwidth.org/profile?user=lj'&gt;&lt;b&gt;lj&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;::MANTICORE is set
— DW::Task::SphinxCopier and the legacy bin/worker/sphinx-copier —
so writes hit both backends during migration without having to redeploy
the webservers.&lt;/p&gt;

&lt;p&gt;t/search.t replaces t/search-manticore.t and targets SphinxQL, since
Manticore 25.0 dropped the legacy Sphinx binary API Sphinx::Search used.&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.7 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;n&amp;#111;r&amp;#101;&amp;#x70;&amp;#x6C;&amp;#121;&amp;#64;&amp;#97;&amp;#x6E;&amp;#116;&amp;#x68;&amp;#x72;&amp;#x6F;&amp;#112;&amp;#105;&amp;#x63;&amp;#46;&amp;#99;&amp;#111;&amp;#x6D;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Compare: https://github.com/dreamwidth/dreamwidth/compare/ba7e09ed3116...8faae76d08f5&lt;/p&gt;

&lt;p&gt;To unsubscribe from these emails, change your notification settings at https://github.com/dreamwidth/dreamwidth/settings/notifications&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=changelog&amp;ditemid=1928515" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-06-03:11:1928423</id>
    <author>
      <name>github</name>
    </author>
    <dw:poster user="github"/>
    <link rel="alternate" type="text/html" href="https://changelog.dreamwidth.org/1928423.html"/>
    <link rel="self" type="text/xml" href="https://changelog.dreamwidth.org/data/atom/?itemid=1928423"/>
    <title>[dreamwidth/dreamwidth] ba7e09: Add t/search-manticore.t: end-to-end test for Sphi...</title>
    <published>2026-04-23T17:16:39Z</published>
    <updated>2026-04-23T17:16:39Z</updated>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='github' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://github.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://github.dreamwidth.org/'&gt;&lt;b&gt;github&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Branch: refs/heads/main
  Home:   https://github.com/dreamwidth/dreamwidth
  Commit: ba7e09ed3116998f6a745752a3a9bc840415912d
      https://github.com/dreamwidth/dreamwidth/commit/ba7e09ed3116998f6a745752a3a9bc840415912d
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;&amp;#109;&amp;#97;&amp;#x72;&amp;#x6B;&amp;#64;&amp;#x64;r&amp;#x65;&amp;#x61;&amp;#x6D;&amp;#x77;i&amp;#x64;&amp;#116;&amp;#x68;&amp;#46;&amp;#x6F;&amp;#x72;&amp;#x67;&lt;/a&gt;
  Date:   2026-04-23 (Thu, 23 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    A t/search-manticore.t&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Add t/search-manticore.t: end-to-end test for Sphinx::Search against Manticore&lt;/p&gt;

&lt;p&gt;Validates the read path of sphinx-search-gm will work when retargeted
at &lt;span style='white-space: nowrap;'&gt;&lt;a href='https://www.dreamwidth.org/profile?user=lj'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://www.dreamwidth.org/profile?user=lj'&gt;&lt;b&gt;lj&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;::MANTICORE — specifically that Sphinx::Search's binary protocol
is accepted on Manticore port 3312, that the filter semantics match
what we expect, and that BuildExcerpts works.&lt;/p&gt;

&lt;p&gt;The test creates a throwaway RT table (dw1_selftest) in Manticore via
SphinxQL CREATE TABLE, populates it with a curated set of docs covering
each test scenario, runs queries, and drops the table at END. Skips
entirely if &lt;span style='white-space: nowrap;'&gt;&lt;a href='https://www.dreamwidth.org/profile?user=lj'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://www.dreamwidth.org/profile?user=lj'&gt;&lt;b&gt;lj&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;::MANTICORE isn't configured, so CI without a Manticore
instance won't fail.&lt;/p&gt;

&lt;p&gt;Covers 15 test cases:
  1.  Baseline keyword match via Sphinx::Search
  2.  Phrase match (SPH_MATCH_PHRASE with quoted query)
  3.  Public entry visible in global search; other entries excluded
  4.  Private entry hidden by security_bits filter
  5.  Private entry visible with ignore_security path
  6.  Friends-only entry: matching allowmask bit returns doc
  7.  Friends-only entry: non-matching allowmask bit excludes doc
  8.  is_deleted=1 filtered out
  9.  allow_global_search=0 excluded from global
  10. Journal-scoped search (journalid filter)
  11. Comments excluded when SetFilterRange('jtalkid', 0, 0)
  12. Comments included when that filter isn't applied
  13. Sort by date_posted, ASC and DESC
  14. BuildExcerpts returns highlighted keyword snippets
  15. Defensive SetFilter('security_bits', [0], 1) exclusion
      (protects against malformed docs with a 0 in their MVA)&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.7 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;n&amp;#x6F;&amp;#114;&amp;#x65;p&amp;#108;&amp;#x79;&amp;#64;&amp;#97;&amp;#110;&amp;#x74;h&amp;#114;o&amp;#x70;&amp;#105;&amp;#99;&amp;#x2E;&amp;#x63;&amp;#111;&amp;#109;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To unsubscribe from these emails, change your notification settings at https://github.com/dreamwidth/dreamwidth/settings/notifications&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=changelog&amp;ditemid=1928423" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-06-03:11:1927972</id>
    <author>
      <name>github</name>
    </author>
    <dw:poster user="github"/>
    <link rel="alternate" type="text/html" href="https://changelog.dreamwidth.org/1927972.html"/>
    <link rel="self" type="text/xml" href="https://changelog.dreamwidth.org/data/atom/?itemid=1927972"/>
    <title>[dreamwidth/dreamwidth] b8e8de: SearchCopier: rewrite as direct port of SphinxCopi...</title>
    <published>2026-04-23T08:36:41Z</published>
    <updated>2026-04-23T08:36:41Z</updated>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='github' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://github.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://github.dreamwidth.org/'&gt;&lt;b&gt;github&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Branch: refs/heads/main
  Home:   https://github.com/dreamwidth/dreamwidth
  Commit: b8e8ded3b31d3871f41a68cf0dc160db5ce18d94
      https://github.com/dreamwidth/dreamwidth/commit/b8e8ded3b31d3871f41a68cf0dc160db5ce18d94
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;&amp;#109;&amp;#97;&amp;#x72;&amp;#107;&amp;#64;&amp;#100;&amp;#x72;&amp;#101;a&amp;#x6D;&amp;#119;&amp;#105;&amp;#x64;&amp;#x74;h.&amp;#x6F;&amp;#x72;&amp;#x67;&lt;/a&gt;
  Date:   2026-04-23 (Thu, 23 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M bin/search-tool
    M cgi-bin/DW/Task/SearchCopier.pm&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;SearchCopier: rewrite as direct port of SphinxCopier patterns&lt;/p&gt;

&lt;p&gt;The prior SearchCopier took its own shape — bulk selectall_arrayref,
ad-hoc chunking, per-doc log lines, wholesale DELETE-then-rebuild per
journal — and missed practices SphinxCopier has been using in prod for
years. Rewrite it as a near-mechanical port of SphinxCopier, with
Manticore-specific deviations only where Manticore's semantics require
them.&lt;/p&gt;

&lt;p&gt;What's now matched with SphinxCopier:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;work() dispatch structure, arg shape (jitemid, jtalkid, jitemids,
jtalkids, full recopy), and log messages at INFO&lt;/li&gt;
&lt;li&gt;sphinx_db()/manticore_db() opens the connection with a SET NAMES
'utf8' and errstr check&lt;/li&gt;
&lt;li&gt;logcroak() after every query against the cluster DB and the search
DB, so failures fail the task loudly and the queue retries&lt;/li&gt;
&lt;li&gt;Full-recopy entry pass diffs dw1 vs log2 and batch-deletes missing
jitemids; does NOT wipe the whole journal up front. Search stays
available for the journal during the recopy.&lt;/li&gt;
&lt;li&gt;Full-recopy comment pass has the "short path" for &lt;/li&gt;&lt;/ul&gt;&lt;div class='ljparseerror'&gt;&lt;strong&gt;( &lt;a href='https://changelog.dreamwidth.org/1927972.html'&gt;Error: Irreparable invalid markup in entry. Raw contents behind the cut.&lt;/a&gt; )&lt;/strong&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=changelog&amp;ditemid=1927972" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-06-03:11:1927724</id>
    <author>
      <name>github</name>
    </author>
    <dw:poster user="github"/>
    <link rel="alternate" type="text/html" href="https://changelog.dreamwidth.org/1927724.html"/>
    <link rel="self" type="text/xml" href="https://changelog.dreamwidth.org/data/atom/?itemid=1927724"/>
    <title>[dreamwidth/dreamwidth] 39a949: SearchCopier: stream from cluster DBs, match Sphin...</title>
    <published>2026-04-23T08:03:19Z</published>
    <updated>2026-04-23T08:03:19Z</updated>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='github' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://github.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://github.dreamwidth.org/'&gt;&lt;b&gt;github&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Branch: refs/heads/main
  Home:   https://github.com/dreamwidth/dreamwidth
  Commit: 39a9497745cdab9f36c8d8cd669f7457a3595fd6
      https://github.com/dreamwidth/dreamwidth/commit/39a9497745cdab9f36c8d8cd669f7457a3595fd6
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;&amp;#x6D;&amp;#x61;&amp;#114;k&amp;#64;&amp;#x64;rea&amp;#x6D;&amp;#x77;&amp;#x69;&amp;#100;t&amp;#x68;.&amp;#111;&amp;#114;&amp;#103;&lt;/a&gt;
  Date:   2026-04-23 (Thu, 23 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M cgi-bin/DW/Task/SearchCopier.pm&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;SearchCopier: stream from cluster DBs, match SphinxCopier logging&lt;/p&gt;

&lt;p&gt;&lt;em&gt;import&lt;/em&gt;full was doing selectall_arrayref on both log2+logtext2 and
talk2+talktext2 for the journal, which loads every row into perl memory
before doing anything. Workers were OOMing on real-world accounts.&lt;/p&gt;

&lt;p&gt;Switched both loops to prepare + execute + fetchrow_hashref with
mysql_use_result=1 so DBD::mysql actually streams rather than buffering
the full result set client-side. Also merged the old "fetch metadata,
then fetch text in batches of 1000" comment path into a single
talk2 + talktext2 join, since we're streaming now. Working memory is
bounded at one row at a time plus the %entry_bits map (jitemid -&amp;gt; bits
arrayref) kept around for comment security inheritance.&lt;/p&gt;

&lt;p&gt;Also upgraded work()'s logging to match SphinxCopier's verbosity so
it's actually possible to tell who a job is for from the logs:
  "Search copier started for &lt;b&gt;[Unknown site tag]&lt;/b&gt;(&lt;id&gt;), source &lt;source&gt;."     INFO
  "Requested copy of only entry &lt;jitemid&gt;."                      INFO
  "Requested copy of only comment &lt;jtalkid&gt;."                    INFO
  "Requested complete recopy of user."                           INFO
  "Copied less than a day ago. Skipping."                        INFO
Start/branch lines emit at INFO; end-of-run summary still DEBUG on
clean success and WARN only when there were errors.&lt;/jtalkid&gt;&lt;/jitemid&gt;&lt;/id&gt;&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.7 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;&amp;#x6E;or&amp;#x65;&amp;#x70;&amp;#x6C;y&amp;#64;&amp;#97;&amp;#110;&amp;#116;&amp;#x68;&amp;#114;&amp;#x6F;&amp;#x70;&amp;#105;&amp;#99;&amp;#46;&amp;#x63;&amp;#x6F;&amp;#109;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To unsubscribe from these emails, change your notification settings at https://github.com/dreamwidth/dreamwidth/settings/notifications&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=changelog&amp;ditemid=1927724" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-06-03:11:1927544</id>
    <author>
      <name>github</name>
    </author>
    <dw:poster user="github"/>
    <link rel="alternate" type="text/html" href="https://changelog.dreamwidth.org/1927544.html"/>
    <link rel="self" type="text/xml" href="https://changelog.dreamwidth.org/data/atom/?itemid=1927544"/>
    <title>[dreamwidth/dreamwidth] 776ac7: Add DW::Task::SearchCopier path and bin/search-tool</title>
    <published>2026-04-23T02:10:55Z</published>
    <updated>2026-04-23T02:10:55Z</updated>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='github' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://github.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://github.dreamwidth.org/'&gt;&lt;b&gt;github&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Branch: refs/heads/main
  Home:   https://github.com/dreamwidth/dreamwidth
  Commit: 776ac7cd8c2185b53beb87c4c460205d19f00be3
      https://github.com/dreamwidth/dreamwidth/commit/776ac7cd8c2185b53beb87c4c460205d19f00be3
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;&amp;#x6D;&amp;#x61;&amp;#x72;&amp;#107;&amp;#64;&amp;#x64;&amp;#x72;&amp;#x65;&amp;#x61;m&amp;#x77;&amp;#105;&amp;#100;&amp;#x74;&amp;#104;&amp;#46;&amp;#x6F;r&amp;#103;&lt;/a&gt;
  Date:   2026-04-23 (Thu, 23 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    A .github/workflows/tasks/worker-dw-search-copier-service.json
    M .github/workflows/worker22-deploy.yml
    R bin/schedule-copier-jobs
    A bin/search-tool
    A bin/worker/dw-search-copier
    A cgi-bin/DW/Task/SearchCopier.pm
    M cgi-bin/LJ/DB.pm
    M config/workers.json
    M etc/workers.conf&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Add DW::Task::SearchCopier path and bin/search-tool&lt;/p&gt;

&lt;p&gt;Stand up the new manticore-rt write path side-by-side with the legacy
sphinx-copier. Nothing in production dispatches to it yet — only
bin/search-tool's import-* subcommands. The two paths can run in
parallel through cutover.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;cgi-bin/DW/Task/SearchCopier.pm: new task class. Auto-routes to its
own SQS queue (dw-prod-dw-task-searchcopier) via class-name
derivation. Mirrors SphinxCopier's argument shape (full recopy,
single jitemid, single jtalkid) and its security_bits / state /
text-decode handling, so the search worker's filter contract stays
intact when we eventually flip readers over. Tracks per-run stats
(entries/comments/deletes ok/err); summary log is debug on clean
success, warn when there are errors. Independent 24h memcache
throttle on full recopies (separate key from sphinx-copier's).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;bin/worker/dw-search-copier: 36-line runner cloned from
dw-sphinx-copier; pulls from the new queue, calls work().&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;etc/workers.conf: add dw-search-copier: 1 so worker-manager spawns it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;bin/search-tool: CLI helper for the migration. Subcommands
import-user, import-all, import-support, search, show, delete,
count, flush. import-user delegates to SearchCopier-&amp;gt;work() so the
CLI and the worker share one code path. import-all replaces the
retired bin/schedule-copier-jobs (deleted in this commit).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;config/workers.json: register dw-search-copier as an ECS Fargate
worker (256 cpu / 512 mb, spot, target 30% cpu, scale 1-10). The
.github/workflows/ files are the auto-generated CI artifacts from
running update-workflows.py.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;LJ/DB.pm: incidental tidyall whitespace-only fixup.&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.7 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;&amp;#x6E;&amp;#x6F;&amp;#x72;e&amp;#112;&amp;#x6C;&amp;#x79;&amp;#64;&amp;#97;&amp;#110;&amp;#x74;&amp;#104;&amp;#x72;&amp;#x6F;&amp;#x70;&amp;#x69;&amp;#99;&amp;#x2E;&amp;#x63;&amp;#111;&amp;#x6D;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To unsubscribe from these emails, change your notification settings at https://github.com/dreamwidth/dreamwidth/settings/notifications&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=changelog&amp;ditemid=1927544" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-06-03:11:1927416</id>
    <author>
      <name>github</name>
    </author>
    <dw:poster user="github"/>
    <link rel="alternate" type="text/html" href="https://changelog.dreamwidth.org/1927416.html"/>
    <link rel="self" type="text/xml" href="https://changelog.dreamwidth.org/data/atom/?itemid=1927416"/>
    <title>[dreamwidth/dreamwidth] d1fab4: Revert self-hosted log shipping, stay on Grafana C...</title>
    <published>2026-04-22T04:26:01Z</published>
    <updated>2026-04-22T04:26:01Z</updated>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='github' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://github.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://github.dreamwidth.org/'&gt;&lt;b&gt;github&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Branch: refs/heads/main
  Home:   https://github.com/dreamwidth/dreamwidth
  Commit: d1fab43e780fd9a699983326b4f82f034763d16d
      https://github.com/dreamwidth/dreamwidth/commit/d1fab43e780fd9a699983326b4f82f034763d16d
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;m&amp;#x61;&amp;#x72;&amp;#x6B;&amp;#64;&amp;#100;&amp;#x72;&amp;#101;&amp;#97;&amp;#109;&amp;#119;&amp;#105;&amp;#100;&amp;#x74;&amp;#104;&amp;#46;&amp;#111;&amp;#x72;&amp;#103;&lt;/a&gt;
  Date:   2026-04-21 (Tue, 21 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M .github/workflows/tasks/worker-birthday-notify-service.json
    M .github/workflows/tasks/worker-change-poster-id-service.json
    M .github/workflows/tasks/worker-codebuild-notifier-service.json
    M .github/workflows/tasks/worker-content-importer-lite-service.json
    M .github/workflows/tasks/worker-content-importer-service.json
    M .github/workflows/tasks/worker-content-importer-verify-service.json
    M .github/workflows/tasks/worker-directory-meta-service.json
    M .github/workflows/tasks/worker-distribute-invites-service.json
    M .github/workflows/tasks/worker-dw-change-poster-id-service.json
    M .github/workflows/tasks/worker-dw-distribute-invites-service.json
    M .github/workflows/tasks/worker-dw-embeds-service.json
    M .github/workflows/tasks/worker-dw-esn-cluster-subs-service.json
    M .github/workflows/tasks/worker-dw-esn-filter-subs-service.json
    M .github/workflows/tasks/worker-dw-esn-fired-event-service.json
    M .github/workflows/tasks/worker-dw-esn-process-sub-service.json
    M .github/workflows/tasks/worker-dw-import-eraser-service.json
    M .github/workflows/tasks/worker-dw-incoming-email-service.json
    M .github/workflows/tasks/worker-dw-latest-feed-service.json
    M .github/workflows/tasks/worker-dw-lazy-cleanup-service.json
    M .github/workflows/tasks/worker-dw-mass-privacy-service.json
    M .github/workflows/tasks/worker-dw-send-email-service.json
    M .github/workflows/tasks/worker-dw-sphinx-copier-service.json
    M .github/workflows/tasks/worker-dw-support-notify-service.json
    M .github/workflows/tasks/worker-dw-synsuck-service.json
    M .github/workflows/tasks/worker-dw-xpost-service.json
    M .github/workflows/tasks/worker-embeds-service.json
    M .github/workflows/tasks/worker-expunge-users-service.json
    M .github/workflows/tasks/worker-import-eraser-service.json
    M .github/workflows/tasks/worker-import-scheduler-service.json
    M .github/workflows/tasks/worker-incoming-email-service.json
    M .github/workflows/tasks/worker-latest-feed-service.json
    M .github/workflows/tasks/worker-lazy-cleanup-service.json
    M .github/workflows/tasks/worker-paidstatus-service.json
    M .github/workflows/tasks/worker-process-privacy-service.json
    M .github/workflows/tasks/worker-resolve-extacct-service.json
    M .github/workflows/tasks/worker-schedule-synsuck-service.json
    M .github/workflows/tasks/worker-ses-incoming-email-service.json
    M .github/workflows/tasks/worker-shop-creditcard-charge-service.json
    M .github/workflows/tasks/worker-spellcheck-gm-service.json
    M .github/workflows/tasks/worker-sphinx-copier-service.json
    M .github/workflows/tasks/worker-sphinx-search-gm-service.json
    M .github/workflows/tasks/worker-support-notify-service.json
    M config/update-workflows.py&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Revert self-hosted log shipping, stay on Grafana Cloud&lt;/p&gt;

&lt;p&gt;With the planned source-side log volume reduction, Grafana Cloud's
per-GB pricing becomes negligible and the operational overhead of
self-hosting (bandwidth, maintenance, availability) isn't worth it.
Points Fluent Bit back at logs-prod-042.grafana.net with the Loki
creds from SSM.&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.7 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;&amp;#x6E;&amp;#x6F;&amp;#114;&amp;#101;&amp;#x70;&amp;#x6C;&amp;#x79;&amp;#64;a&amp;#x6E;&amp;#x74;&amp;#104;&amp;#x72;&amp;#111;&amp;#112;&amp;#105;&amp;#x63;&amp;#46;&amp;#x63;&amp;#111;&amp;#x6D;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Commit: 28416189e56cdbf33dffa19ff486b97ffdad2848
      https://github.com/dreamwidth/dreamwidth/commit/28416189e56cdbf33dffa19ff486b97ffdad2848
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;&amp;#x6D;&amp;#x61;&amp;#114;k&amp;#64;&amp;#x64;&amp;#114;&amp;#x65;&amp;#x61;&amp;#109;w&amp;#105;d&amp;#x74;h.o&amp;#114;g&lt;/a&gt;
  Date:   2026-04-21 (Tue, 21 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M cgi-bin/LJ/ESN.pm
    M etc/log4perl.conf&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Reduce log volume: trim log4perl layout and drop duplicate ESN rejection log&lt;/p&gt;

&lt;p&gt;Two small changes that together cut log bytes substantially:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;etc/log4perl.conf: drop %F:%L %M from the conversion pattern. File,
line, and function name added ~80 bytes of framing to every line
system-wide; they're rarely useful since the trace prefix and message
already identify the code path, and esn-trace searches by trace ID
rather than file/line.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cgi-bin/LJ/ESN.pm: remove the filter_reject debug log in
unique_matching_subs. The callee-side log in
JournalNewComment::matches_filter already logs every rejection with
strictly more information (reason, wanted_jtalkid), so the caller-
side log was pure duplication. The dw.esn.filter metric stays.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Together these eliminate roughly half of every ESN filter-rejection
pair plus ~40% bytes on every log line.&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.7 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;&amp;#x6E;&amp;#111;&amp;#x72;&amp;#101;&amp;#112;&amp;#x6C;&amp;#121;&amp;#64;&amp;#97;&amp;#x6E;&amp;#x74;&amp;#104;&amp;#114;&amp;#x6F;&amp;#x70;&amp;#105;&amp;#99;&amp;#46;&amp;#x63;&amp;#x6F;&amp;#x6D;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Compare: https://github.com/dreamwidth/dreamwidth/compare/005e4d64c9d3...28416189e56c&lt;/p&gt;

&lt;p&gt;To unsubscribe from these emails, change your notification settings at https://github.com/dreamwidth/dreamwidth/settings/notifications&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=changelog&amp;ditemid=1927416" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-06-03:11:1927111</id>
    <author>
      <name>github</name>
    </author>
    <dw:poster user="github"/>
    <link rel="alternate" type="text/html" href="https://changelog.dreamwidth.org/1927111.html"/>
    <link rel="self" type="text/xml" href="https://changelog.dreamwidth.org/data/atom/?itemid=1927111"/>
    <title>[dreamwidth/dreamwidth] c5763c: Fix stringified site object in extacct stats tag</title>
    <published>2026-04-22T03:26:09Z</published>
    <updated>2026-04-22T03:26:09Z</updated>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='github' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://github.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://github.dreamwidth.org/'&gt;&lt;b&gt;github&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Branch: refs/heads/main
  Home:   https://github.com/dreamwidth/dreamwidth
  Commit: c5763c345a2ef2f8e69074808482cb6361f66c7e
      https://github.com/dreamwidth/dreamwidth/commit/c5763c345a2ef2f8e69074808482cb6361f66c7e
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;&amp;#x6D;&amp;#x61;&amp;#x72;&amp;#107;&amp;#64;d&amp;#x72;&amp;#x65;&amp;#97;&amp;#109;&amp;#x77;&amp;#105;&amp;#x64;&amp;#116;&amp;#x68;&amp;#46;o&amp;#x72;&amp;#x67;&lt;/a&gt;
  Date:   2026-04-20 (Mon, 20 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M cgi-bin/DW/External/Userinfo.pm&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Fix stringified site object in extacct stats tag&lt;/p&gt;

&lt;p&gt;DW::External::Site-&amp;gt;get_site_by_id returns a blessed hashref, and
concatenating with "site:" triggered Perl's default stringification,
producing values like 'site:DW::External::Site::DeadJournal=HASH(0x...)'.
The hash address was effectively a new label value per process, so
every worker restart created a fresh set of unique series that lingered
in the active-series count until they aged out. Use -&amp;gt;{hostname} to
emit stable values like 'site:livejournal.com'.&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.7 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;n&amp;#x6F;&amp;#114;&amp;#x65;&amp;#x70;&amp;#108;&amp;#121;&amp;#64;&amp;#97;&amp;#110;&amp;#116;&amp;#x68;&amp;#114;&amp;#x6F;&amp;#x70;&amp;#105;&amp;#x63;&amp;#46;&amp;#x63;&amp;#x6F;&amp;#x6D;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Commit: 005e4d64c9d3d9359de4cff0c3232d2887b06632
      https://github.com/dreamwidth/dreamwidth/commit/005e4d64c9d3d9359de4cff0c3232d2887b06632
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;&amp;#109;&amp;#x61;&amp;#x72;&amp;#107;&amp;#64;&amp;#100;&amp;#114;&amp;#101;&amp;#97;&amp;#109;&amp;#x77;&amp;#105;&amp;#100;&amp;#x74;&amp;#x68;&amp;#46;&amp;#x6F;&amp;#114;&amp;#x67;&lt;/a&gt;
  Date:   2026-04-21 (Tue, 21 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M .github/workflows/tasks/worker-birthday-notify-service.json
    M .github/workflows/tasks/worker-change-poster-id-service.json
    M .github/workflows/tasks/worker-codebuild-notifier-service.json
    M .github/workflows/tasks/worker-content-importer-lite-service.json
    M .github/workflows/tasks/worker-content-importer-service.json
    M .github/workflows/tasks/worker-content-importer-verify-service.json
    M .github/workflows/tasks/worker-directory-meta-service.json
    M .github/workflows/tasks/worker-distribute-invites-service.json
    M .github/workflows/tasks/worker-dw-change-poster-id-service.json
    M .github/workflows/tasks/worker-dw-distribute-invites-service.json
    M .github/workflows/tasks/worker-dw-embeds-service.json
    M .github/workflows/tasks/worker-dw-esn-cluster-subs-service.json
    M .github/workflows/tasks/worker-dw-esn-filter-subs-service.json
    M .github/workflows/tasks/worker-dw-esn-fired-event-service.json
    M .github/workflows/tasks/worker-dw-esn-process-sub-service.json
    M .github/workflows/tasks/worker-dw-import-eraser-service.json
    M .github/workflows/tasks/worker-dw-incoming-email-service.json
    M .github/workflows/tasks/worker-dw-latest-feed-service.json
    M .github/workflows/tasks/worker-dw-lazy-cleanup-service.json
    M .github/workflows/tasks/worker-dw-mass-privacy-service.json
    M .github/workflows/tasks/worker-dw-send-email-service.json
    M .github/workflows/tasks/worker-dw-sphinx-copier-service.json
    M .github/workflows/tasks/worker-dw-support-notify-service.json
    M .github/workflows/tasks/worker-dw-synsuck-service.json
    M .github/workflows/tasks/worker-dw-xpost-service.json
    M .github/workflows/tasks/worker-embeds-service.json
    M .github/workflows/tasks/worker-expunge-users-service.json
    M .github/workflows/tasks/worker-import-eraser-service.json
    M .github/workflows/tasks/worker-import-scheduler-service.json
    M .github/workflows/tasks/worker-incoming-email-service.json
    M .github/workflows/tasks/worker-latest-feed-service.json
    M .github/workflows/tasks/worker-lazy-cleanup-service.json
    M .github/workflows/tasks/worker-paidstatus-service.json
    M .github/workflows/tasks/worker-process-privacy-service.json
    M .github/workflows/tasks/worker-resolve-extacct-service.json
    M .github/workflows/tasks/worker-schedule-synsuck-service.json
    M .github/workflows/tasks/worker-ses-incoming-email-service.json
    M .github/workflows/tasks/worker-shop-creditcard-charge-service.json
    M .github/workflows/tasks/worker-spellcheck-gm-service.json
    M .github/workflows/tasks/worker-sphinx-copier-service.json
    M .github/workflows/tasks/worker-sphinx-search-gm-service.json
    M .github/workflows/tasks/worker-support-notify-service.json
    M config/update-workflows.py&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Switch to self-hosted log service&lt;/p&gt;

&lt;p&gt;I don't really want to pay hundreds/month for storing logs and I have a server hanging
out that has fast disks/RAM, might as well just self-host it. It's not production so
if it dies, I can always revert/fix.&lt;/p&gt;

&lt;p&gt;Compare: https://github.com/dreamwidth/dreamwidth/compare/ad345841bf9b...005e4d64c9d3&lt;/p&gt;

&lt;p&gt;To unsubscribe from these emails, change your notification settings at https://github.com/dreamwidth/dreamwidth/settings/notifications&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=changelog&amp;ditemid=1927111" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-06-03:11:1926765</id>
    <author>
      <name>github</name>
    </author>
    <dw:poster user="github"/>
    <link rel="alternate" type="text/html" href="https://changelog.dreamwidth.org/1926765.html"/>
    <link rel="self" type="text/xml" href="https://changelog.dreamwidth.org/data/atom/?itemid=1926765"/>
    <title>[dreamwidth/dreamwidth] 6dc7b3: Drop high-cardinality username tag from extacct stats</title>
    <published>2026-04-20T23:11:45Z</published>
    <updated>2026-04-20T23:11:45Z</updated>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='github' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://github.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://github.dreamwidth.org/'&gt;&lt;b&gt;github&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Branch: refs/heads/main
  Home:   https://github.com/dreamwidth/dreamwidth
  Commit: 6dc7b32ef3eed8378f40270d35c3a0b7a45dd21b
      https://github.com/dreamwidth/dreamwidth/commit/6dc7b32ef3eed8378f40270d35c3a0b7a45dd21b
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;&amp;#x6D;&amp;#97;&amp;#114;&amp;#x6B;&amp;#64;&amp;#100;&amp;#114;&amp;#101;&amp;#97;m&amp;#119;&amp;#105;&amp;#x64;&amp;#116;&amp;#104;&amp;#46;&amp;#111;r&amp;#103;&lt;/a&gt;
  Date:   2026-04-20 (Mon, 20 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M cgi-bin/DW/External/Userinfo.pm&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Drop high-cardinality username tag from extacct stats&lt;/p&gt;

&lt;p&gt;The username:$user tag on dw.worker.extacct.{success,failure} tracked
each remote external-site user individually, making it the top metric
by active series count in Grafana Cloud billing. Site alone is bounded
to the DW::External::Site enum and gives the actionable dimension.&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.7 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;&amp;#x6E;&amp;#x6F;&amp;#114;&amp;#101;&amp;#112;&amp;#108;y&amp;#64;&amp;#97;&amp;#x6E;t&amp;#x68;&amp;#x72;&amp;#111;&amp;#112;&amp;#105;&amp;#99;.&amp;#x63;&amp;#x6F;&amp;#109;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Commit: ad345841bf9b424ceb6bf65be2136b88fb612301
      https://github.com/dreamwidth/dreamwidth/commit/ad345841bf9b424ceb6bf65be2136b88fb612301
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;&amp;#109;&amp;#97;&amp;#x72;&amp;#107;&amp;#64;&amp;#x64;&amp;#114;&amp;#101;&amp;#97;m&amp;#x77;i&amp;#x64;&amp;#116;&amp;#104;&amp;#46;&amp;#x6F;&amp;#x72;&amp;#x67;&lt;/a&gt;
  Date:   2026-04-20 (Mon, 20 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M cgi-bin/DW/Controller/Importer.pm
    M cgi-bin/DW/Logic/Importer.pm&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Validate importer hostname against source whitelist&lt;/p&gt;

&lt;p&gt;The /tools/importer UI offered a dropdown of three allowed sources
(livejournal.com, insanejournal.com, dreamwidth.org), but
set_import_data_for_user accepted whatever hostname the POST carried
and INSERTed it straight into import_data. A crafted POST could inject
arbitrary hostnames, which then flowed into the new hostname: tag on
dw.worker.importer.job_completed as a cardinality-injection vector.&lt;/p&gt;

&lt;p&gt;Extracts the allowed-source list into DW::Logic::Importer-&amp;gt;allowed_sources
so the controller's dropdown rendering and the logic layer's validation
share one definition, and rejects any hostname not in the list.&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.7 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;&amp;#x6E;&amp;#x6F;r&amp;#101;&amp;#x70;l&amp;#121;&amp;#64;&amp;#x61;&amp;#x6E;&amp;#x74;&amp;#104;&amp;#x72;&amp;#x6F;&amp;#112;&amp;#105;&amp;#99;.c&amp;#111;&amp;#x6D;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Compare: https://github.com/dreamwidth/dreamwidth/compare/00b8f85a98e0...ad345841bf9b&lt;/p&gt;

&lt;p&gt;To unsubscribe from these emails, change your notification settings at https://github.com/dreamwidth/dreamwidth/settings/notifications&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=changelog&amp;ditemid=1926765" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-06-03:11:1926428</id>
    <author>
      <name>github</name>
    </author>
    <dw:poster user="github"/>
    <link rel="alternate" type="text/html" href="https://changelog.dreamwidth.org/1926428.html"/>
    <link rel="self" type="text/xml" href="https://changelog.dreamwidth.org/data/atom/?itemid=1926428"/>
    <title>[dreamwidth/dreamwidth] 00b8f8: Add JSON access log middleware for Grafana Loki</title>
    <published>2026-04-19T19:35:10Z</published>
    <updated>2026-04-19T19:35:10Z</updated>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='github' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://github.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://github.dreamwidth.org/'&gt;&lt;b&gt;github&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Branch: refs/heads/main
  Home:   https://github.com/dreamwidth/dreamwidth
  Commit: 00b8f85a98e039eaaf2046ccb2bbc7e1ff07d60e
      https://github.com/dreamwidth/dreamwidth/commit/00b8f85a98e039eaaf2046ccb2bbc7e1ff07d60e
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;&amp;#x6D;&amp;#97;&amp;#114;&amp;#107;&amp;#64;&amp;#x64;&amp;#x72;&amp;#x65;&amp;#x61;&amp;#109;&amp;#x77;&amp;#x69;&amp;#100;th.&amp;#111;&amp;#114;&amp;#103;&lt;/a&gt;
  Date:   2026-04-19 (Sun, 19 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M app.psgi
    M bin/starman
    A cgi-bin/Plack/Middleware/DW/AccessLog.pm&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Add JSON access log middleware for Grafana Loki&lt;/p&gt;

&lt;p&gt;Replace Starman's default Apache Combined access log with a DW::AccessLog
middleware that emits one JSON object per line to psgi.errors. Fields include
method, path, status, bytes, duration_ms, host, remote_ip, and user_agent —
all natively parseable by Loki's &lt;code&gt;| json&lt;/code&gt; pipeline for dashboards.&lt;/p&gt;

&lt;p&gt;Use --no-default-middleware to suppress Plack's built-in AccessLog, and
enable ContentLength explicitly in app.psgi to preserve that behavior.&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.6 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;&amp;#110;&amp;#111;&amp;#114;&amp;#x65;&amp;#112;&amp;#108;&amp;#x79;&amp;#64;&amp;#97;&amp;#x6E;&amp;#x74;&amp;#104;&amp;#114;opi&amp;#99;.&amp;#x63;&amp;#111;&amp;#x6D;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To unsubscribe from these emails, change your notification settings at https://github.com/dreamwidth/dreamwidth/settings/notifications&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=changelog&amp;ditemid=1926428" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-06-03:11:1926345</id>
    <author>
      <name>github</name>
    </author>
    <dw:poster user="github"/>
    <link rel="alternate" type="text/html" href="https://changelog.dreamwidth.org/1926345.html"/>
    <link rel="self" type="text/xml" href="https://changelog.dreamwidth.org/data/atom/?itemid=1926345"/>
    <title>[dreamwidth/dreamwidth] a19cc8: Improve esn-trace URL resolution with userid looku...</title>
    <published>2026-04-13T06:12:02Z</published>
    <updated>2026-04-13T06:12:02Z</updated>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='github' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://github.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://github.dreamwidth.org/'&gt;&lt;b&gt;github&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Branch: refs/heads/main
  Home:   https://github.com/dreamwidth/dreamwidth
  Commit: a19cc8c787fca5419d8469a5977323ed68c450c2
      https://github.com/dreamwidth/dreamwidth/commit/a19cc8c787fca5419d8469a5977323ed68c450c2
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;&amp;#x6D;a&amp;#114;k&amp;#64;&amp;#x64;r&amp;#101;&amp;#97;&amp;#109;&amp;#119;&amp;#x69;&amp;#x64;&amp;#x74;&amp;#104;&amp;#46;&amp;#x6F;&amp;#x72;&amp;#x67;&lt;/a&gt;
  Date:   2026-04-12 (Sun, 12 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M src/dwtool/main.go&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Improve esn-trace URL resolution with userid lookup and precise Loki queries&lt;/p&gt;

&lt;p&gt;Resolve the journal's userid from their profile page so we can build exact
Loki regex queries matching [esn ETYPEID:JOURNALID:JTALKID:ARG2] instead of
broad substring matches on ":JTALKID:" which produced false positives.&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.6 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;&amp;#x6E;&amp;#111;&amp;#114;e&amp;#x70;&amp;#x6C;&amp;#121;&amp;#64;&amp;#97;&amp;#110;&amp;#116;&amp;#x68;ro&amp;#112;i&amp;#x63;&amp;#x2E;&amp;#x63;&amp;#x6F;&amp;#x6D;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Commit: b1e684b607034fa480f654db748922660b063d9d
      https://github.com/dreamwidth/dreamwidth/commit/b1e684b607034fa480f654db748922660b063d9d
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;&amp;#x6D;&amp;#97;rk&amp;#64;&amp;#x64;&amp;#114;&amp;#x65;&amp;#97;&amp;#109;&amp;#119;i&amp;#100;&amp;#116;&amp;#104;&amp;#x2E;&amp;#111;&amp;#114;&amp;#x67;&lt;/a&gt;
  Date:   2026-04-12 (Sun, 12 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M cgi-bin/DW/Task/ESN/FiredEvent.pm
    M cgi-bin/LJ/DB.pm&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Fix ESN dropping notifications due to replication lag on comment load&lt;/p&gt;

&lt;p&gt;FiredEvent reads comment data to determine which users' Reply subscriptions
are relevant. LJ::Comment::preload_rows loads via get_cluster_reader, which
hits the replica — but the comment was just written to the master and may not
have replicated yet. When this race is lost, the comment fails to load,
&lt;em&gt;relevant&lt;/em&gt;userids returns empty, Reply subscriptions are excluded, and the
notification is silently dropped.&lt;/p&gt;

&lt;p&gt;Fix: wrap the subscription lookup in LJ::DB::require_master so all reads
go to the cluster master. Also extend get_cluster_reader to respect the
existing &lt;em&gt;PRAGMA&lt;/em&gt;FORCE_MASTER flag, which previously only affected global
(non-cluster) readers.&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.6 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;&amp;#110;&amp;#x6F;&amp;#114;&amp;#x65;&amp;#x70;&amp;#108;&amp;#x79;&amp;#64;&amp;#x61;&amp;#x6E;t&amp;#x68;&amp;#114;o&amp;#x70;&amp;#105;&amp;#x63;&amp;#x2E;&amp;#x63;&amp;#x6F;&amp;#109;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Compare: https://github.com/dreamwidth/dreamwidth/compare/eae7aaa21ba6...b1e684b60703&lt;/p&gt;

&lt;p&gt;To unsubscribe from these emails, change your notification settings at https://github.com/dreamwidth/dreamwidth/settings/notifications&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=changelog&amp;ditemid=1926345" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-06-03:11:1926030</id>
    <author>
      <name>github</name>
    </author>
    <dw:poster user="github"/>
    <link rel="alternate" type="text/html" href="https://changelog.dreamwidth.org/1926030.html"/>
    <link rel="self" type="text/xml" href="https://changelog.dreamwidth.org/data/atom/?itemid=1926030"/>
    <title>[dreamwidth/dreamwidth] 439d83: Switch dwtool log-scan and esn-trace from CloudWat...</title>
    <published>2026-04-12T17:09:34Z</published>
    <updated>2026-04-12T17:09:34Z</updated>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='github' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://github.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://github.dreamwidth.org/'&gt;&lt;b&gt;github&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Branch: refs/heads/main
  Home:   https://github.com/dreamwidth/dreamwidth
  Commit: 439d836de1e77290f029a08afebd37d4b177f74f
      https://github.com/dreamwidth/dreamwidth/commit/439d836de1e77290f029a08afebd37d4b177f74f
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;m&amp;#x61;&amp;#x72;&amp;#x6B;&amp;#64;&amp;#100;&amp;#x72;&amp;#101;&amp;#x61;&amp;#109;&amp;#x77;&amp;#x69;&amp;#100;&amp;#116;&amp;#x68;&amp;#x2E;&amp;#x6F;r&amp;#103;&lt;/a&gt;
  Date:   2026-04-12 (Sun, 12 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    A src/dwtool/internal/config/loki.go
    A src/dwtool/internal/loki/client.go
    M src/dwtool/main.go&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Switch dwtool log-scan and esn-trace from CloudWatch to Loki&lt;/p&gt;

&lt;p&gt;Logs now go directly to Grafana Cloud Loki via Fluent Bit, so dwtool
needs to query Loki instead of CloudWatch. Adds a Loki HTTP client
that queries /loki/api/v1/query_range with LogQL, and rewrites both
log-scan and esn-trace to use it.&lt;/p&gt;

&lt;p&gt;Credentials are loaded from ~/.config/dwtool/config.json (with
DWTOOL_LOKI_HOST/USER/PASSWORD env var overrides). The Loki client
strips Fluent Bit key_value wrapper and log4perl timestamp/level
prefix from messages so output is clean.&lt;/p&gt;

&lt;p&gt;Other fixes:
- Renamed logscan → log-scan for consistency with esn-trace
- Fixed flag parsing in esn-trace: Go's flag package stops at the
  first positional arg, so &lt;code&gt;esn-trace URL -since 24h&lt;/code&gt; silently
  ignored -since. Args are now reordered so flags come first.
- log-scan uses -service instead of -groups for filtering by Loki
  service label instead of CloudWatch log group glob
- Service column is hidden when -service is specified (redundant)&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.6 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;no&amp;#x72;&amp;#x65;&amp;#112;&amp;#108;&amp;#x79;&amp;#64;a&amp;#x6E;&amp;#x74;&amp;#104;r&amp;#111;&amp;#112;&amp;#105;&amp;#x63;&amp;#x2E;&amp;#x63;&amp;#x6F;&amp;#109;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Commit: eae7aaa21ba6b5d07a1ed3378505a9a0b156b995
      https://github.com/dreamwidth/dreamwidth/commit/eae7aaa21ba6b5d07a1ed3378505a9a0b156b995
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;&amp;#x6D;&amp;#x61;&amp;#114;&amp;#x6B;&amp;#64;&amp;#100;&amp;#114;&amp;#101;&amp;#x61;&amp;#109;&amp;#x77;&amp;#x69;&amp;#100;&amp;#x74;h&amp;#46;&amp;#111;r&amp;#103;&lt;/a&gt;
  Date:   2026-04-12 (Sun, 12 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M .github/workflows/tasks/web-canary-service.json
    M .github/workflows/tasks/web-shop-service.json
    M .github/workflows/tasks/web-stable-service.json
    M .github/workflows/tasks/web-unauthenticated-service.json&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;remove cloudwatch agent sidecar from web task definitions&lt;/p&gt;

&lt;p&gt;The CW agent was configured to collect Apache access logs but was
pointing at a -DISABLED log path, so it was burning resources for
nothing. Removes the sidecar container, log-share volume, and
associated mount from all four web service task definitions.&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.6 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;&amp;#110;&amp;#111;&amp;#x72;&amp;#x65;&amp;#112;l&amp;#121;&amp;#64;&amp;#x61;&amp;#x6E;&amp;#116;&amp;#x68;r&amp;#x6F;&amp;#x70;&amp;#x69;&amp;#x63;&amp;#46;&amp;#99;&amp;#111;&amp;#x6D;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Compare: https://github.com/dreamwidth/dreamwidth/compare/b046642d6f54...eae7aaa21ba6&lt;/p&gt;

&lt;p&gt;To unsubscribe from these emails, change your notification settings at https://github.com/dreamwidth/dreamwidth/settings/notifications&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=changelog&amp;ditemid=1926030" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-06-03:11:1925675</id>
    <author>
      <name>github</name>
    </author>
    <dw:poster user="github"/>
    <link rel="alternate" type="text/html" href="https://changelog.dreamwidth.org/1925675.html"/>
    <link rel="self" type="text/xml" href="https://changelog.dreamwidth.org/data/atom/?itemid=1925675"/>
    <title>[dreamwidth/dreamwidth] b04664: Ship worker logs directly to Grafana Cloud Loki vi...</title>
    <published>2026-04-12T08:03:53Z</published>
    <updated>2026-04-12T08:03:53Z</updated>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='github' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://github.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://github.dreamwidth.org/'&gt;&lt;b&gt;github&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Branch: refs/heads/main
  Home:   https://github.com/dreamwidth/dreamwidth
  Commit: b046642d6f54f301e4f4a128472cc9edfa8fd80c
      https://github.com/dreamwidth/dreamwidth/commit/b046642d6f54f301e4f4a128472cc9edfa8fd80c
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;m&amp;#97;&amp;#114;&amp;#107;&amp;#64;&amp;#x64;&amp;#x72;&amp;#101;a&amp;#x6D;&amp;#119;&amp;#x69;&amp;#100;&amp;#x74;&amp;#104;&amp;#46;&amp;#x6F;&amp;#114;&amp;#x67;&lt;/a&gt;
  Date:   2026-04-12 (Sun, 12 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M .github/workflows/tasks/worker-birthday-notify-service.json
    M .github/workflows/tasks/worker-change-poster-id-service.json
    M .github/workflows/tasks/worker-codebuild-notifier-service.json
    M .github/workflows/tasks/worker-content-importer-lite-service.json
    M .github/workflows/tasks/worker-content-importer-service.json
    M .github/workflows/tasks/worker-content-importer-verify-service.json
    M .github/workflows/tasks/worker-directory-meta-service.json
    M .github/workflows/tasks/worker-distribute-invites-service.json
    M .github/workflows/tasks/worker-dw-change-poster-id-service.json
    M .github/workflows/tasks/worker-dw-distribute-invites-service.json
    M .github/workflows/tasks/worker-dw-embeds-service.json
    M .github/workflows/tasks/worker-dw-esn-cluster-subs-service.json
    M .github/workflows/tasks/worker-dw-esn-filter-subs-service.json
    M .github/workflows/tasks/worker-dw-esn-fired-event-service.json
    M .github/workflows/tasks/worker-dw-esn-process-sub-service.json
    M .github/workflows/tasks/worker-dw-import-eraser-service.json
    M .github/workflows/tasks/worker-dw-incoming-email-service.json
    M .github/workflows/tasks/worker-dw-latest-feed-service.json
    M .github/workflows/tasks/worker-dw-lazy-cleanup-service.json
    M .github/workflows/tasks/worker-dw-mass-privacy-service.json
    M .github/workflows/tasks/worker-dw-send-email-service.json
    M .github/workflows/tasks/worker-dw-sphinx-copier-service.json
    M .github/workflows/tasks/worker-dw-support-notify-service.json
    M .github/workflows/tasks/worker-dw-synsuck-service.json
    M .github/workflows/tasks/worker-dw-xpost-service.json
    M .github/workflows/tasks/worker-embeds-service.json
    M .github/workflows/tasks/worker-expunge-users-service.json
    M .github/workflows/tasks/worker-import-eraser-service.json
    M .github/workflows/tasks/worker-import-scheduler-service.json
    M .github/workflows/tasks/worker-incoming-email-service.json
    M .github/workflows/tasks/worker-latest-feed-service.json
    M .github/workflows/tasks/worker-lazy-cleanup-service.json
    M .github/workflows/tasks/worker-paidstatus-service.json
    M .github/workflows/tasks/worker-process-privacy-service.json
    M .github/workflows/tasks/worker-resolve-extacct-service.json
    M .github/workflows/tasks/worker-schedule-synsuck-service.json
    M .github/workflows/tasks/worker-ses-incoming-email-service.json
    M .github/workflows/tasks/worker-shop-creditcard-charge-service.json
    M .github/workflows/tasks/worker-spellcheck-gm-service.json
    M .github/workflows/tasks/worker-sphinx-copier-service.json
    M .github/workflows/tasks/worker-sphinx-search-gm-service.json
    M .github/workflows/tasks/worker-support-notify-service.json
    M config/update-workflows.py&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Ship worker logs directly to Grafana Cloud Loki via Fluent Bit&lt;/p&gt;

&lt;p&gt;Regenerated all 42 worker task definitions to use awsfirelens with a
Fluent Bit log_router sidecar instead of the awslogs driver. Worker
logs now go directly to Grafana Cloud Loki over HTTPS, bypassing
CloudWatch Logs entirely.&lt;/p&gt;

&lt;p&gt;Each task definition gains a log_router container (~15MB RSS) running
aws-for-fluent-bit:3 (Fluent Bit v4.2.2, the 3.x line based on
AL2023 — the 2.x line ships Fluent Bit 1.9 which has no Loki plugin).
Loki credentials are injected via SSM secrets at task startup. The
worker container's logDriver changes from awslogs to awsfirelens with
the native loki output plugin.&lt;/p&gt;

&lt;p&gt;Fluent Bit's own logs still go to CloudWatch (/dreamwidth/fluent-bit)
so the log router itself can be debugged if needed.&lt;/p&gt;

&lt;p&gt;Generated by config/update-workflows.py from config/workers.json.&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.6 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;&amp;#x6E;&amp;#x6F;&amp;#114;&amp;#101;p&amp;#108;&amp;#121;&amp;#64;&amp;#x61;&amp;#x6E;&amp;#x74;&amp;#x68;&amp;#114;&amp;#111;&amp;#112;&amp;#105;&amp;#99;&amp;#x2E;&amp;#99;&amp;#111;&amp;#x6D;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To unsubscribe from these emails, change your notification settings at https://github.com/dreamwidth/dreamwidth/settings/notifications&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=changelog&amp;ditemid=1925675" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-06-03:11:1925630</id>
    <author>
      <name>github</name>
    </author>
    <dw:poster user="github"/>
    <link rel="alternate" type="text/html" href="https://changelog.dreamwidth.org/1925630.html"/>
    <link rel="self" type="text/xml" href="https://changelog.dreamwidth.org/data/atom/?itemid=1925630"/>
    <title>[dreamwidth/dreamwidth] ece0b7: Ship worker logs directly to Grafana Cloud Loki vi...</title>
    <published>2026-04-12T07:42:19Z</published>
    <updated>2026-04-12T07:42:19Z</updated>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='github' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://github.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://github.dreamwidth.org/'&gt;&lt;b&gt;github&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Branch: refs/heads/main
  Home:   https://github.com/dreamwidth/dreamwidth
  Commit: ece0b7970913514a534e88d20b8383a4555ebe5a
      https://github.com/dreamwidth/dreamwidth/commit/ece0b7970913514a534e88d20b8383a4555ebe5a
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;&amp;#x6D;&amp;#x61;&amp;#x72;&amp;#x6B;&amp;#64;&amp;#100;&amp;#114;e&amp;#x61;&amp;#x6D;&amp;#x77;&amp;#105;&amp;#100;&amp;#x74;&amp;#x68;&amp;#x2E;&amp;#111;&amp;#x72;g&lt;/a&gt;
  Date:   2026-04-12 (Sun, 12 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M .github/workflows/tasks/worker-birthday-notify-service.json
    M .github/workflows/tasks/worker-change-poster-id-service.json
    M .github/workflows/tasks/worker-codebuild-notifier-service.json
    M .github/workflows/tasks/worker-content-importer-lite-service.json
    M .github/workflows/tasks/worker-content-importer-service.json
    M .github/workflows/tasks/worker-content-importer-verify-service.json
    M .github/workflows/tasks/worker-directory-meta-service.json
    M .github/workflows/tasks/worker-distribute-invites-service.json
    M .github/workflows/tasks/worker-dw-change-poster-id-service.json
    M .github/workflows/tasks/worker-dw-distribute-invites-service.json
    M .github/workflows/tasks/worker-dw-embeds-service.json
    M .github/workflows/tasks/worker-dw-esn-cluster-subs-service.json
    M .github/workflows/tasks/worker-dw-esn-filter-subs-service.json
    M .github/workflows/tasks/worker-dw-esn-fired-event-service.json
    M .github/workflows/tasks/worker-dw-esn-process-sub-service.json
    M .github/workflows/tasks/worker-dw-import-eraser-service.json
    M .github/workflows/tasks/worker-dw-incoming-email-service.json
    M .github/workflows/tasks/worker-dw-latest-feed-service.json
    M .github/workflows/tasks/worker-dw-lazy-cleanup-service.json
    M .github/workflows/tasks/worker-dw-mass-privacy-service.json
    M .github/workflows/tasks/worker-dw-send-email-service.json
    M .github/workflows/tasks/worker-dw-sphinx-copier-service.json
    M .github/workflows/tasks/worker-dw-support-notify-service.json
    M .github/workflows/tasks/worker-dw-synsuck-service.json
    M .github/workflows/tasks/worker-dw-xpost-service.json
    M .github/workflows/tasks/worker-embeds-service.json
    M .github/workflows/tasks/worker-expunge-users-service.json
    M .github/workflows/tasks/worker-import-eraser-service.json
    M .github/workflows/tasks/worker-import-scheduler-service.json
    M .github/workflows/tasks/worker-incoming-email-service.json
    M .github/workflows/tasks/worker-latest-feed-service.json
    M .github/workflows/tasks/worker-lazy-cleanup-service.json
    M .github/workflows/tasks/worker-paidstatus-service.json
    M .github/workflows/tasks/worker-process-privacy-service.json
    M .github/workflows/tasks/worker-resolve-extacct-service.json
    M .github/workflows/tasks/worker-schedule-synsuck-service.json
    M .github/workflows/tasks/worker-ses-incoming-email-service.json
    M .github/workflows/tasks/worker-shop-creditcard-charge-service.json
    M .github/workflows/tasks/worker-spellcheck-gm-service.json
    M .github/workflows/tasks/worker-sphinx-copier-service.json
    M .github/workflows/tasks/worker-sphinx-search-gm-service.json
    M .github/workflows/tasks/worker-support-notify-service.json
    M config/update-workflows.py&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Ship worker logs directly to Grafana Cloud Loki via Fluent Bit&lt;/p&gt;

&lt;p&gt;Regenerated all 42 worker task definitions to use awsfirelens with a
Fluent Bit log_router sidecar instead of the awslogs driver. Worker
logs now go directly to Grafana Cloud Loki over HTTPS, bypassing
CloudWatch Logs entirely.&lt;/p&gt;

&lt;p&gt;Each task definition gains a log_router container (~15MB RSS) running
the AWS-maintained Fluent Bit image from private ECR. Loki credentials
are injected via SSM secrets at task startup. The worker container's
logDriver changes from awslogs to awsfirelens with the grafana-loki
output plugin.&lt;/p&gt;

&lt;p&gt;Fluent Bit's own logs still go to CloudWatch (/dreamwidth/fluent-bit)
so the log router itself can be debugged if needed.&lt;/p&gt;

&lt;p&gt;Generated by config/update-workflows.py from config/workers.json.&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.6 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;&amp;#110;&amp;#111;&amp;#x72;&amp;#x65;&amp;#112;&amp;#x6C;&amp;#121;&amp;#64;&amp;#97;&amp;#110;&amp;#116;&amp;#104;&amp;#x72;&amp;#x6F;&amp;#x70;&amp;#x69;c&amp;#x2E;&amp;#x63;&amp;#111;m&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Commit: 0d49a7588ae0544ef51801c977e8df41c651e3b5
      https://github.com/dreamwidth/dreamwidth/commit/0d49a7588ae0544ef51801c977e8df41c651e3b5
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;&amp;#x6D;&amp;#x61;&amp;#x72;&amp;#x6B;&amp;#64;&amp;#100;&amp;#114;&amp;#101;&amp;#97;&amp;#x6D;&amp;#119;i&amp;#100;&amp;#x74;&amp;#104;.&amp;#x6F;&amp;#x72;&amp;#x67;&lt;/a&gt;
  Date:   2026-04-12 (Sun, 12 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M cgi-bin/DW/Worker/ContentImporter.pm
    M cgi-bin/DW/Worker/ContentImporter/LiveJournal.pm&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;tidy&lt;/p&gt;

&lt;p&gt;Compare: https://github.com/dreamwidth/dreamwidth/compare/d7d5b8fbd0bb...0d49a7588ae0&lt;/p&gt;

&lt;p&gt;To unsubscribe from these emails, change your notification settings at https://github.com/dreamwidth/dreamwidth/settings/notifications&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=changelog&amp;ditemid=1925630" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-06-03:11:1925150</id>
    <author>
      <name>github</name>
    </author>
    <dw:poster user="github"/>
    <link rel="alternate" type="text/html" href="https://changelog.dreamwidth.org/1925150.html"/>
    <link rel="self" type="text/xml" href="https://changelog.dreamwidth.org/data/atom/?itemid=1925150"/>
    <title>[dreamwidth/dreamwidth] d7d5b8: Auto-deactivate ESN subscriptions for idle users</title>
    <published>2026-04-12T07:09:29Z</published>
    <updated>2026-04-12T07:09:29Z</updated>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='github' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://github.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://github.dreamwidth.org/'&gt;&lt;b&gt;github&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Branch: refs/heads/main
  Home:   https://github.com/dreamwidth/dreamwidth
  Commit: d7d5b8fbd0bb1063688f06cc820d3e65bae09a45
      https://github.com/dreamwidth/dreamwidth/commit/d7d5b8fbd0bb1063688f06cc820d3e65bae09a45
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;m&amp;#x61;&amp;#x72;k&amp;#64;&amp;#100;&amp;#x72;&amp;#x65;&amp;#x61;&amp;#x6D;&amp;#119;&amp;#105;&amp;#100;&amp;#x74;&amp;#x68;.o&amp;#x72;&amp;#x67;&lt;/a&gt;
  Date:   2026-04-12 (Sun, 12 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M cgi-bin/DW/Task/ESN/ProcessSub.pm
    M cgi-bin/LJ/ESN.pm
    M etc/config-local.pl.example&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Auto-deactivate ESN subscriptions for idle users&lt;/p&gt;

&lt;p&gt;When processing notifications, deactivate subscriptions that belong to
users who have been idle for over a year ($LJ::ESN_INACTIVE_DAYS,
default 365). This happens in two places:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;LJ::ESN::unique_matching_subs: if a sub requires a paid capability
the user no longer has (e.g. thread tracking after paid expired) AND
the user is idle, deactivate the sub before it reaches matches_filter.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DW::Task::ESN::ProcessSub: if a user is idle, deactivate the sub
after the first skip so it never generates another SQS job.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Deactivated subs set the INACTIVE flag, NOT deleted. The user can
still see them on /manage/tracking and reactivate them when they
return. LJ::Subscription::create also automatically reactivates
matching inactive subs when a user re-subscribes.&lt;/p&gt;

&lt;p&gt;The idle threshold is configurable via $LJ::ESN_INACTIVE_DAYS in
config-local.pl (documented in the example file). The same variable
is used for the existing ProcessSub idle-skip check, replacing a
previously hardcoded 365.&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.6 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;&amp;#x6E;&amp;#111;&amp;#x72;&amp;#x65;&amp;#x70;&amp;#108;&amp;#x79;&amp;#64;&amp;#x61;&amp;#110;t&amp;#104;&amp;#114;&amp;#111;&amp;#x70;&amp;#105;c&amp;#x2E;&amp;#x63;&amp;#x6F;&amp;#x6D;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To unsubscribe from these emails, change your notification settings at https://github.com/dreamwidth/dreamwidth/settings/notifications&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=changelog&amp;ditemid=1925150" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-06-03:11:1924913</id>
    <author>
      <name>github</name>
    </author>
    <dw:poster user="github"/>
    <link rel="alternate" type="text/html" href="https://changelog.dreamwidth.org/1924913.html"/>
    <link rel="self" type="text/xml" href="https://changelog.dreamwidth.org/data/atom/?itemid=1924913"/>
    <title>[dreamwidth/dreamwidth] 51d098: Support parallel worktree devcontainers for multi-...</title>
    <published>2026-04-12T06:41:46Z</published>
    <updated>2026-04-12T06:41:46Z</updated>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='github' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://github.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://github.dreamwidth.org/'&gt;&lt;b&gt;github&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Branch: refs/heads/main
  Home:   https://github.com/dreamwidth/dreamwidth
  Commit: 51d098321baa231958385df0c938af13be280ccb
      https://github.com/dreamwidth/dreamwidth/commit/51d098321baa231958385df0c938af13be280ccb
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;&amp;#109;&amp;#97;&amp;#114;&amp;#x6B;&amp;#64;&amp;#100;&amp;#114;&amp;#101;&amp;#x61;&amp;#109;&amp;#119;&amp;#x69;&amp;#100;&amp;#x74;&amp;#104;&amp;#x2E;&amp;#111;&amp;#x72;&amp;#x67;&lt;/a&gt;
  Date:   2026-04-11 (Sat, 11 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M .devcontainer/devcontainer.json
    M .devcontainer/setup.sh
    M CLAUDE.md&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Support parallel worktree devcontainers for multi-Claude workflows&lt;/p&gt;

&lt;p&gt;Three fixes that allow multiple devcontainers to run simultaneously
from git worktrees without conflicts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add workspaceMount to always bind-mount at /workspaces/dreamwidth
regardless of host folder name (worktrees have different names)&lt;/li&gt;
&lt;li&gt;Use dynamic host ports (-p 0:8080) instead of hardcoded 8080:8080
so multiple containers don't fight over the same port&lt;/li&gt;
&lt;li&gt;Give each workspace its own MySQL volume to prevent DB corruption&lt;/li&gt;
&lt;li&gt;Symlink extlib from the image when it doesn't exist on disk (worktrees
don't have extlib/ since it's gitignored)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.6 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;&amp;#x6E;&amp;#111;&amp;#114;&amp;#101;&amp;#112;&amp;#108;&amp;#121;&amp;#64;&amp;#97;&amp;#110;&amp;#116;&amp;#104;&amp;#x72;&amp;#111;&amp;#x70;&amp;#105;c&amp;#46;&amp;#x63;&amp;#111;&amp;#109;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Commit: 3fcdc3a52918fb76bc84761b4428b66cce064066
      https://github.com/dreamwidth/dreamwidth/commit/3fcdc3a52918fb76bc84761b4428b66cce064066
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;&amp;#x6D;&amp;#97;&amp;#x72;&amp;#x6B;&amp;#64;&amp;#100;&amp;#114;&amp;#101;&amp;#97;&amp;#x6D;&amp;#x77;&amp;#x69;&amp;#x64;&amp;#x74;&amp;#104;&amp;#x2E;&amp;#111;&amp;#114;&amp;#x67;&lt;/a&gt;
  Date:   2026-04-11 (Sat, 11 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M cgi-bin/LJ/Comment.pm&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Add per-check diagnostic logging to Comment::visible_to&lt;/p&gt;

&lt;p&gt;When called during ESN processing (CURRENT_TRACE is set), visible_to
now logs which specific check caused the rejection: entry_not_loaded,
entry_not_visible (with security level), screened, or poster_suspended.
Previously all four cases produced a generic not_visible_to_watcher in
the matches_filter trace with no way to distinguish them after the fact.&lt;/p&gt;

&lt;p&gt;Triggered by a real case (trace 3:2296509:6184:0) where all 40
subscribers were rejected with not_visible_to_watcher on a public
unscreened comment in a personal journal — couldn't determine root
cause without per-check visibility.&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.6 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;&amp;#110;&amp;#111;&amp;#x72;&amp;#101;&amp;#x70;&amp;#108;&amp;#x79;&amp;#64;&amp;#97;&amp;#x6E;&amp;#x74;&amp;#104;&amp;#x72;&amp;#x6F;&amp;#112;&amp;#x69;&amp;#99;&amp;#x2E;&amp;#x63;&amp;#111;&amp;#x6D;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Compare: https://github.com/dreamwidth/dreamwidth/compare/1c54be1b97b9...3fcdc3a52918&lt;/p&gt;

&lt;p&gt;To unsubscribe from these emails, change your notification settings at https://github.com/dreamwidth/dreamwidth/settings/notifications&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=changelog&amp;ditemid=1924913" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-06-03:11:1924844</id>
    <author>
      <name>github</name>
    </author>
    <dw:poster user="github"/>
    <link rel="alternate" type="text/html" href="https://changelog.dreamwidth.org/1924844.html"/>
    <link rel="self" type="text/xml" href="https://changelog.dreamwidth.org/data/atom/?itemid=1924844"/>
    <title>[dreamwidth/dreamwidth] 1c54be: Fix false send failures and add CLI improvements</title>
    <published>2026-04-12T05:53:29Z</published>
    <updated>2026-04-12T05:53:29Z</updated>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='github' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://github.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://github.dreamwidth.org/'&gt;&lt;b&gt;github&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Branch: refs/heads/main
  Home:   https://github.com/dreamwidth/dreamwidth
  Commit: 1c54be1b97b9d64d8833b984f942a9b66d326643
      https://github.com/dreamwidth/dreamwidth/commit/1c54be1b97b9d64d8833b984f942a9b66d326643
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;&amp;#x6D;&amp;#x61;r&amp;#107;&amp;#64;&amp;#x64;&amp;#x72;&amp;#x65;&amp;#97;&amp;#109;&amp;#119;&amp;#x69;&amp;#100;&amp;#x74;h&amp;#46;&amp;#x6F;&amp;#114;&amp;#x67;&lt;/a&gt;
  Date:   2026-04-11 (Sat, 11 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M cgi-bin/DW/Task/ESN/FilterSubs.pm
    M cgi-bin/DW/Task/ESN/FindSubsByCluster.pm
    M src/dwtool/main.go&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Fix false send failures and add CLI improvements&lt;/p&gt;

&lt;p&gt;FilterSubs and FindSubsByCluster were passing the result of
tasks_of_unique_matching_subs() directly to DW::TaskQueue-&amp;gt;send(),
which returns undef on an empty task list. When all subscriptions
were legitimately filtered out by matches_filter, this was counted
as a "failed send" (~47 false failures/min). Split the calls so
empty task lists are a normal completion, not an error.&lt;/p&gt;

&lt;p&gt;Also adds top-level help to dwtool listing available subcommands,
and teaches esn-trace to accept a comment URL (parses ?thread=
param, converts dtalkid to jtalkid, searches fired-event logs for
the full trace ID automatically).&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.6 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;nor&amp;#x65;&amp;#x70;&amp;#108;&amp;#121;&amp;#64;&amp;#97;&amp;#x6E;&amp;#x74;&amp;#104;&amp;#x72;&amp;#x6F;&amp;#112;&amp;#105;&amp;#99;&amp;#46;c&amp;#x6F;&amp;#109;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To unsubscribe from these emails, change your notification settings at https://github.com/dreamwidth/dreamwidth/settings/notifications&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=changelog&amp;ditemid=1924844" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-06-03:11:1924499</id>
    <author>
      <name>github</name>
    </author>
    <dw:poster user="github"/>
    <link rel="alternate" type="text/html" href="https://changelog.dreamwidth.org/1924499.html"/>
    <link rel="self" type="text/xml" href="https://changelog.dreamwidth.org/data/atom/?itemid=1924499"/>
    <title>[dreamwidth/dreamwidth] c3394d: Add DW::Stats metrics to content importer job outc...</title>
    <published>2026-04-12T05:01:58Z</published>
    <updated>2026-04-12T05:01:58Z</updated>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='github' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://github.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://github.dreamwidth.org/'&gt;&lt;b&gt;github&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Branch: refs/heads/main
  Home:   https://github.com/dreamwidth/dreamwidth
  Commit: c3394d8c9d9ca1cbd8e169d3a1e85849e9affbaa
      https://github.com/dreamwidth/dreamwidth/commit/c3394d8c9d9ca1cbd8e169d3a1e85849e9affbaa
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;m&amp;#97;&amp;#x72;&amp;#107;&amp;#64;&amp;#100;&amp;#114;&amp;#x65;&amp;#97;&amp;#x6D;&amp;#x77;&amp;#105;&amp;#100;&amp;#116;&amp;#x68;&amp;#x2E;&amp;#111;&amp;#x72;&amp;#103;&lt;/a&gt;
  Date:   2026-04-11 (Sat, 11 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M cgi-bin/DW/Worker/ContentImporter.pm&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Add DW::Stats metrics to content importer job outcomes&lt;/p&gt;

&lt;p&gt;Instrument all four outcome methods (ok, fail, temp_fail, decline) in
DW::Worker::ContentImporter with a single metric
dw.worker.importer.job_completed, using labels for result, item, and
hostname to support Prometheus-style querying.&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.6 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;&amp;#x6E;&amp;#x6F;&amp;#x72;&amp;#x65;&amp;#x70;&amp;#x6C;&amp;#121;&amp;#64;&amp;#97;&amp;#110;&amp;#x74;&amp;#104;&amp;#114;&amp;#111;&amp;#112;i&amp;#99;&amp;#46;&amp;#99;&amp;#x6F;m&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To unsubscribe from these emails, change your notification settings at https://github.com/dreamwidth/dreamwidth/settings/notifications&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=changelog&amp;ditemid=1924499" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-06-03:11:1924304</id>
    <author>
      <name>github</name>
    </author>
    <dw:poster user="github"/>
    <link rel="alternate" type="text/html" href="https://changelog.dreamwidth.org/1924304.html"/>
    <link rel="self" type="text/xml" href="https://changelog.dreamwidth.org/data/atom/?itemid=1924304"/>
    <title>[dreamwidth/dreamwidth] 034f12: Add deterministic ESN trace IDs and full pipeline ...</title>
    <published>2026-04-12T04:57:17Z</published>
    <updated>2026-04-12T04:57:17Z</updated>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='github' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://github.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://github.dreamwidth.org/'&gt;&lt;b&gt;github&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Branch: refs/heads/main
  Home:   https://github.com/dreamwidth/dreamwidth
  Commit: 034f12e28b75c1c3b3ce7b6ab173616484e33ee5
      https://github.com/dreamwidth/dreamwidth/commit/034f12e28b75c1c3b3ce7b6ab173616484e33ee5
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;m&amp;#x61;&amp;#114;&amp;#107;&amp;#64;&amp;#100;&amp;#114;&amp;#101;&amp;#x61;&amp;#109;&amp;#x77;&amp;#105;&amp;#100;&amp;#116;&amp;#104;&amp;#x2E;&amp;#111;&amp;#x72;&amp;#x67;&lt;/a&gt;
  Date:   2026-04-11 (Sat, 11 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M cgi-bin/DW/Task/ESN/FilterSubs.pm
    M cgi-bin/DW/Task/ESN/FindSubsByCluster.pm
    M cgi-bin/DW/Task/ESN/FiredEvent.pm
    M cgi-bin/DW/Task/ESN/ProcessSub.pm
    M cgi-bin/LJ/ESN.pm
    M cgi-bin/LJ/Event/JournalNewComment.pm
    M cgi-bin/LJ/NotificationInbox.pm
    M cgi-bin/LJ/Subscription.pm
    M src/dwtool/main.go&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Add deterministic ESN trace IDs and full pipeline observability&lt;/p&gt;

&lt;p&gt;Every ESN log line now carries a deterministic trace prefix
[esn ETYPEID:JOURNALID:ARG1:ARG2] derived from the event's raw_params,
making end-to-end tracing possible by grepping a single string across
all four ESN worker log groups. The trace ID is computable from a
comment URL without needing to capture it at event-fire time.&lt;/p&gt;

&lt;p&gt;Pipeline changes:
- All four ESN task workers (FiredEvent, FindSubsByCluster, FilterSubs,
  ProcessSub) prefix every log line with the trace string
- LJ::ESN::unique_matching_subs replaces the silent grep with a loop
  that logs each matches_filter rejection at DEBUG with user/sub/etypeid
- JournalNewComment::matches_filter logs specific rejection reasons at
  each of its 9 return-0 paths via a $reject-&amp;gt;() closure
- Subscription::process logs notification construction failures and
  not_configured_for_user skips with trace prefix
- NotificationInbox::enqueue logs successful delivery confirmation
- FindSubsByCluster now checks TaskQueue-&amp;gt;send() return values and
  logs users with &amp;gt;5000 subs that get silently skipped
- FilterSubs now checks TaskQueue-&amp;gt;send() return value
- ProcessSub dead code fixed: subscription-not-found is correctly
  handled as a skip (COMPLETED) not routed through $failed (FAILED)&lt;/p&gt;

&lt;p&gt;Metrics consolidation (Prometheus best practice):
- All DW::Stats calls use one metric name per stage with a result tag
  instead of encoding the result in the metric name
- dw.esn.firedevent       result:started|completed|failed
- dw.esn.findsubsbycluster result:started|completed|failed
- dw.esn.filtersubs       result:completed|dropped|failed
- dw.esn.filter           result:rejected
- dw.esn.matches_filter   result:rejected  (with reason tag)
- dw.esn.processsub       result:processed|skipped|failed
- dw.esn.process          result:failed|skipped
- dw.esn.inbox            result:delivered|evicted&lt;/p&gt;

&lt;p&gt;CLI tooling:
- dwtool esn-trace &lt;etypeid:journalid:arg1:arg2&gt; searches all four ESN
  log groups in CloudWatch and pretty-prints a cross-stage timeline&lt;/etypeid:journalid:arg1:arg2&gt;&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.6 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;&amp;#110;&amp;#111;&amp;#x72;&amp;#x65;p&amp;#x6C;&amp;#121;&amp;#64;&amp;#97;&amp;#x6E;&amp;#116;&amp;#x68;&amp;#x72;&amp;#111;&amp;#112;&amp;#105;&amp;#99;&amp;#x2E;&amp;#99;&amp;#x6F;m&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To unsubscribe from these emails, change your notification settings at https://github.com/dreamwidth/dreamwidth/settings/notifications&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=changelog&amp;ditemid=1924304" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-06-03:11:1924072</id>
    <author>
      <name>github</name>
    </author>
    <dw:poster user="github"/>
    <link rel="alternate" type="text/html" href="https://changelog.dreamwidth.org/1924072.html"/>
    <link rel="self" type="text/xml" href="https://changelog.dreamwidth.org/data/atom/?itemid=1924072"/>
    <title>[dreamwidth/dreamwidth] 62c0b8: Remove legacy web image from web-canary and web-un...</title>
    <published>2026-04-12T04:42:50Z</published>
    <updated>2026-04-12T04:42:50Z</updated>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='github' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://github.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://github.dreamwidth.org/'&gt;&lt;b&gt;github&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Branch: refs/heads/main
  Home:   https://github.com/dreamwidth/dreamwidth
  Commit: 62c0b8e4ee1d12728c8f737eac0061161522fdaa
      https://github.com/dreamwidth/dreamwidth/commit/62c0b8e4ee1d12728c8f737eac0061161522fdaa
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;&amp;#x6D;&amp;#97;&amp;#x72;&amp;#107;&amp;#64;&amp;#100;&amp;#114;&amp;#x65;&amp;#x61;m&amp;#x77;&amp;#105;&amp;#x64;&amp;#x74;&amp;#104;&amp;#46;&amp;#x6F;&amp;#x72;&amp;#x67;&lt;/a&gt;
  Date:   2026-04-11 (Sat, 11 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M src/dwtool/internal/aws/ecs.go&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Remove legacy web image from web-canary and web-unauthenticated deploy targets&lt;/p&gt;

&lt;p&gt;Both services are now fully on web22. This removes the old "web" option
from the deploy flow so only web22 is offered, matching web-shop.&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.6 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;&amp;#110;&amp;#x6F;&amp;#114;&amp;#101;&amp;#112;&amp;#x6C;&amp;#121;&amp;#64;&amp;#97;&amp;#x6E;&amp;#x74;&amp;#x68;&amp;#114;&amp;#111;pi&amp;#99;&amp;#46;&amp;#99;&amp;#111;&amp;#x6D;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Commit: 58ffd06e3da3ae4ea7b3122dac7a46685a4c35e4
      https://github.com/dreamwidth/dreamwidth/commit/58ffd06e3da3ae4ea7b3122dac7a46685a4c35e4
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;&amp;#x6D;&amp;#97;&amp;#114;&amp;#x6B;&amp;#64;d&amp;#114;&amp;#101;&amp;#x61;&amp;#x6D;&amp;#x77;&amp;#105;&amp;#100;&amp;#x74;&amp;#x68;&amp;#x2E;&amp;#111;&amp;#x72;&amp;#x67;&lt;/a&gt;
  Date:   2026-04-11 (Sat, 11 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M .gitignore&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;.gitignore updates&lt;/p&gt;

&lt;p&gt;Commit: 7cbc4931b3974ac99de9e3657f389ed8125a5566
      https://github.com/dreamwidth/dreamwidth/commit/7cbc4931b3974ac99de9e3657f389ed8125a5566
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;&amp;#109;&amp;#97;&amp;#x72;&amp;#x6B;&amp;#64;&amp;#x64;&amp;#x72;&amp;#101;&amp;#x61;&amp;#109;&amp;#x77;&amp;#105;&amp;#100;&amp;#116;&amp;#x68;&amp;#46;&amp;#x6F;&amp;#114;&amp;#x67;&lt;/a&gt;
  Date:   2026-04-11 (Sat, 11 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M cgi-bin/DW/Worker/ContentImporter/LiveJournal.pm
    M doc/dependencies-cpanm&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Fix content-importer-verify TLS connection failures&lt;/p&gt;

&lt;p&gt;The importer's XMLRPC calls to remote LJ-based sites were failing with
"SSL wants a read first" due to a TLS 1.3 handshake issue with
IO::Socket::SSL 2.098 and OpenSSL 3.0 (see openssl/openssl#7967).
Force TLS 1.2 in call_xmlrpc as a workaround.&lt;/p&gt;

&lt;p&gt;Also add missing Regexp::IPv6 dependency, which IO::Socket::IP needs
for address parsing — its absence caused a secondary "Can't locate
Regexp/IPv6.pm" failure.&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.6 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;&amp;#x6E;&amp;#111;&amp;#x72;&amp;#101;p&amp;#x6C;&amp;#x79;&amp;#64;&amp;#x61;&amp;#x6E;&amp;#x74;&amp;#104;&amp;#114;&amp;#x6F;&amp;#x70;&amp;#105;&amp;#99;&amp;#46;&amp;#99;&amp;#111;&amp;#x6D;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Commit: 9eff707e837547024e178f5b0b8cbc30c6653350
      https://github.com/dreamwidth/dreamwidth/commit/9eff707e837547024e178f5b0b8cbc30c6653350
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;m&amp;#97;&amp;#114;&amp;#107;&amp;#64;&amp;#x64;&amp;#114;&amp;#x65;&amp;#97;&amp;#109;&amp;#x77;&amp;#x69;&amp;#100;&amp;#x74;&amp;#104;.&amp;#111;&amp;#114;&amp;#x67;&lt;/a&gt;
  Date:   2026-04-11 (Sat, 11 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    A bin/dev/importer-debug
    M bin/ecs-shell&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Add importer-debug diagnostic script and fix ecs-shell on macOS&lt;/p&gt;

&lt;p&gt;Add bin/dev/importer-debug for diagnosing content-importer connectivity
issues on ECS containers. Tests DNS, TCP, TLS, HTTP, and XMLRPC layers
independently with timing and detailed error output.&lt;/p&gt;

&lt;p&gt;Fix ecs-shell exec command failing on macOS due to base64 -w0 flag not
being supported (macOS uses base64 -i instead).&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.6 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;&amp;#x6E;&amp;#111;&amp;#114;&amp;#101;&amp;#112;&amp;#x6C;&amp;#121;&amp;#64;&amp;#97;nt&amp;#x68;r&amp;#x6F;&amp;#112;&amp;#x69;&amp;#x63;&amp;#x2E;&amp;#x63;&amp;#111;&amp;#109;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Compare: https://github.com/dreamwidth/dreamwidth/compare/388d47d72bfa...9eff707e8375&lt;/p&gt;

&lt;p&gt;To unsubscribe from these emails, change your notification settings at https://github.com/dreamwidth/dreamwidth/settings/notifications&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=changelog&amp;ditemid=1924072" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-06-03:11:1923762</id>
    <author>
      <name>github</name>
    </author>
    <dw:poster user="github"/>
    <link rel="alternate" type="text/html" href="https://changelog.dreamwidth.org/1923762.html"/>
    <link rel="self" type="text/xml" href="https://changelog.dreamwidth.org/data/atom/?itemid=1923762"/>
    <title>[dreamwidth/dreamwidth] 388d47: Add JSON wire format for task queue with gradual r...</title>
    <published>2026-04-12T02:42:06Z</published>
    <updated>2026-04-12T02:42:06Z</updated>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='github' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://github.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://github.dreamwidth.org/'&gt;&lt;b&gt;github&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Branch: refs/heads/main
  Home:   https://github.com/dreamwidth/dreamwidth
  Commit: 388d47d72bfa348ef6378e9f5e638e9fa85da491
      https://github.com/dreamwidth/dreamwidth/commit/388d47d72bfa348ef6378e9f5e638e9fa85da491
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;m&amp;#97;&amp;#114;&amp;#x6B;&amp;#64;d&amp;#114;&amp;#x65;&amp;#97;m&amp;#119;&amp;#x69;&amp;#100;&amp;#116;&amp;#x68;&amp;#46;&amp;#111;r&amp;#x67;&lt;/a&gt;
  Date:   2026-04-11 (Sat, 11 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M cgi-bin/DW/Task.pm
    M cgi-bin/DW/TaskQueue/LocalDisk.pm
    M cgi-bin/DW/TaskQueue/SQS.pm
    M etc/config-local.pl.example
    A t/taskqueue-serialize.t
    A t/taskqueue.t&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Add JSON wire format for task queue with gradual rollout support&lt;/p&gt;

&lt;p&gt;Adds serialize/deserialize methods to DW::Task that support a new v2 JSON
wire format alongside the legacy Storable format. This enables non-Perl
consumers (e.g. Go workers) to read task queue messages.&lt;/p&gt;

&lt;p&gt;$LJ::TASK_QUEUE_JSON controls the rollout as a float 0-1 (e.g. 0.01 = 1%
of messages serialized as JSON). Default is 0 (all Storable). All consumers
can read both formats regardless of this setting. If JSON encoding fails
for a task (e.g. blessed objects in args), it falls back to Storable with
a warning and stat tag identifying the task class.&lt;/p&gt;

&lt;p&gt;Also adds task queue config documentation to config-local.pl.example and
comprehensive test coverage for LocalDisk lifecycle, serialization
round-trips, and queue_attributes.&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.6 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;&amp;#110;&amp;#111;&amp;#114;&amp;#101;&amp;#112;&amp;#x6C;&amp;#x79;&amp;#64;&amp;#97;&amp;#110;&amp;#x74;&amp;#104;&amp;#114;&amp;#x6F;&amp;#x70;&amp;#x69;&amp;#99;&amp;#46;&amp;#99;&amp;#x6F;&amp;#109;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To unsubscribe from these emails, change your notification settings at https://github.com/dreamwidth/dreamwidth/settings/notifications&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=changelog&amp;ditemid=1923762" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-06-03:11:1923406</id>
    <author>
      <name>github</name>
    </author>
    <dw:poster user="github"/>
    <link rel="alternate" type="text/html" href="https://changelog.dreamwidth.org/1923406.html"/>
    <link rel="self" type="text/xml" href="https://changelog.dreamwidth.org/data/atom/?itemid=1923406"/>
    <title>[dreamwidth/dreamwidth] 4d50f4: Add ESN drop/skip observability at silent-failure ...</title>
    <published>2026-04-11T21:11:03Z</published>
    <updated>2026-04-11T21:11:03Z</updated>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='github' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://github.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://github.dreamwidth.org/'&gt;&lt;b&gt;github&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Branch: refs/heads/main
  Home:   https://github.com/dreamwidth/dreamwidth
  Commit: 4d50f4a1d495408fb95df32a63239b8bf7ea60b7
      https://github.com/dreamwidth/dreamwidth/commit/4d50f4a1d495408fb95df32a63239b8bf7ea60b7
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;m&amp;#x61;&amp;#x72;&amp;#107;&amp;#64;&amp;#x64;&amp;#x72;&amp;#101;&amp;#x61;&amp;#x6D;wi&amp;#x64;&amp;#116;&amp;#104;&amp;#46;&amp;#111;&amp;#114;&amp;#x67;&lt;/a&gt;
  Date:   2026-04-11 (Sat, 11 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M cgi-bin/DW/Task/ESN/FilterSubs.pm
    M cgi-bin/DW/Task/ESN/ProcessSub.pm
    M cgi-bin/LJ/NotificationInbox.pm
    M cgi-bin/LJ/Subscription.pm&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Add ESN drop/skip observability at silent-failure points&lt;/p&gt;

&lt;p&gt;The ESN pipeline had several silent-drop paths where notifications could
disappear without any log trace, making "notification went missing" bug
reports impossible to investigate. This adds structured log lines and
DW::Stats counters at four of those paths:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;FilterSubs: the cluster-filter grep was a silent drop for both
legitimate user-moved-cluster cases and (suspected) DB-pressure
partial-load cases from LJ::load_userids. Now logs each drop at INFO
with user=name(uid) sub=N cluster=expected-&amp;gt;got reason=... and
increments dw.esn.filtersubs.dropped tagged by reason.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ProcessSub: the three existing skip paths (subscription_not_found,
user_idle, user_not_visible) kept their DEBUG log level but gained
structured fields and dw.esn.processsub.skipped counters. Added a
dw.esn.processsub.processed counter on the success path so baseline
delivery rate is visible in Datadog.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Subscription::process: the configured_for_user and officialpost
no-op paths now log at DEBUG with structured fields and increment
dw.esn.process.skipped.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;NotificationInbox::enqueue: inbox overflow eviction now logs at
INFO with the user, oldest-kept qid, rows deleted, and max size,
and increments dw.esn.inbox.evicted by the number of rows evicted.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Log levels: rare exceptions (filtersubs drop, inbox eviction) at INFO;
routine skip paths (user idle, not configured) at DEBUG. Stats counters
fire regardless of log level -- Datadog metrics are the primary signal,
logs are forensic backup.&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.6 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;&amp;#x6E;or&amp;#101;&amp;#x70;&amp;#108;y&amp;#64;&amp;#x61;&amp;#x6E;&amp;#x74;&amp;#x68;r&amp;#x6F;&amp;#x70;&amp;#105;&amp;#99;&amp;#x2E;&amp;#x63;&amp;#111;&amp;#x6D;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To unsubscribe from these emails, change your notification settings at https://github.com/dreamwidth/dreamwidth/settings/notifications&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=changelog&amp;ditemid=1923406" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-06-03:11:1923084</id>
    <author>
      <name>github</name>
    </author>
    <dw:poster user="github"/>
    <link rel="alternate" type="text/html" href="https://changelog.dreamwidth.org/1923084.html"/>
    <link rel="self" type="text/xml" href="https://changelog.dreamwidth.org/data/atom/?itemid=1923084"/>
    <title>[dreamwidth/dreamwidth] 727c49: Add logscan CLI subcommand and build helper script...</title>
    <published>2026-04-11T21:01:17Z</published>
    <updated>2026-04-11T21:01:17Z</updated>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='github' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://github.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://github.dreamwidth.org/'&gt;&lt;b&gt;github&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Branch: refs/heads/main
  Home:   https://github.com/dreamwidth/dreamwidth
  Commit: 727c496a47ff8257b62e438d302f0ca999c54d36
      https://github.com/dreamwidth/dreamwidth/commit/727c496a47ff8257b62e438d302f0ca999c54d36
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;&amp;#x6D;&amp;#x61;&amp;#114;&amp;#107;&amp;#64;&amp;#x64;r&amp;#x65;&amp;#97;&amp;#x6D;w&amp;#x69;d&amp;#x74;&amp;#104;&amp;#46;&amp;#111;&amp;#x72;&amp;#x67;&lt;/a&gt;
  Date:   2026-04-11 (Sat, 11 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M src/dwtool/internal/aws/cloudwatch.go
    M src/dwtool/main.go
    A src/dwtool/run.sh&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Add logscan CLI subcommand and build helper script to dwtool&lt;/p&gt;

&lt;p&gt;Adds &lt;code&gt;dwtool logscan&lt;/code&gt; for searching CloudWatch logs across all Dreamwidth
services by keyword, with time range and log group glob filtering. Searches
in 1-hour chunks (newest first) so results stream incrementally. Also adds
run.sh to check dependencies, build, and run dwtool in one step.&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.6 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;&amp;#110;&amp;#111;&amp;#x72;&amp;#101;&amp;#x70;&amp;#108;&amp;#121;&amp;#64;&amp;#97;nt&amp;#104;&amp;#x72;&amp;#x6F;&amp;#112;&amp;#105;&amp;#99;&amp;#46;&amp;#99;&amp;#111;&amp;#x6D;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Commit: d81f640239516e9c21e95a6afdc73f4fc4d63156
      https://github.com/dreamwidth/dreamwidth/commit/d81f640239516e9c21e95a6afdc73f4fc4d63156
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;&amp;#x6D;&amp;#97;&amp;#x72;k&amp;#64;&amp;#100;&amp;#x72;ea&amp;#109;&amp;#119;&amp;#105;&amp;#100;&amp;#x74;&amp;#104;&amp;#x2E;&amp;#x6F;&amp;#114;&amp;#x67;&lt;/a&gt;
  Date:   2026-04-11 (Sat, 11 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M cgi-bin/Plack/Middleware/DW/WriteTimeout.pm
    M t/plack-write-timeout.t&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Tidy fixes&lt;/p&gt;

&lt;p&gt;Compare: https://github.com/dreamwidth/dreamwidth/compare/fe8199f3512e...d81f64023951&lt;/p&gt;

&lt;p&gt;To unsubscribe from these emails, change your notification settings at https://github.com/dreamwidth/dreamwidth/settings/notifications&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=changelog&amp;ditemid=1923084" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-06-03:11:1922946</id>
    <author>
      <name>github</name>
    </author>
    <dw:poster user="github"/>
    <link rel="alternate" type="text/html" href="https://changelog.dreamwidth.org/1922946.html"/>
    <link rel="self" type="text/xml" href="https://changelog.dreamwidth.org/data/atom/?itemid=1922946"/>
    <title>[dreamwidth/dreamwidth] f3e043: Bump github.com/aws/aws-sdk-go-v2/aws/protocol/eve...</title>
    <published>2026-04-08T02:21:00Z</published>
    <updated>2026-04-08T02:21:00Z</updated>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='github' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://github.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://github.dreamwidth.org/'&gt;&lt;b&gt;github&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Branch: refs/heads/dependabot/go_modules/src/dwtool/github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream-1.7.8
  Home:   https://github.com/dreamwidth/dreamwidth
  Commit: f3e04318ef316bae959895f96be292c59b8f5a14
      https://github.com/dreamwidth/dreamwidth/commit/f3e04318ef316bae959895f96be292c59b8f5a14
  Author: dependabot[bot] &amp;lt;49699333+dependabot[bot]&lt;span style='white-space: nowrap;'&gt;&lt;a href='http://www.github.com/users/'&gt;&lt;img src='https://www.dreamwidth.org/img/profile_icons/github.png' alt='[github.com profile] ' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' width='16' height='16'/&gt;&lt;/a&gt;&lt;a href='http://www.github.com/users'&gt;&lt;b&gt;users&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&amp;gt;
  Date:   2026-04-08 (Wed, 08 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M src/dwtool/go.mod
    M src/dwtool/go.sum&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Bump github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream&lt;/p&gt;

&lt;p&gt;Bumps &lt;a href="https://github.com/aws/aws-sdk-go-v2"&gt;github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream&lt;/a&gt; from 1.7.4 to 1.7.8.
- &lt;a href="https://github.com/aws/aws-sdk-go-v2/releases"&gt;Release notes&lt;/a&gt;
- &lt;a href="https://github.com/aws/aws-sdk-go-v2/compare/service/m2/v1.7.4...service/m2/v1.7.8"&gt;Commits&lt;/a&gt;&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=changelog&amp;ditemid=1922946" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-06-03:11:1922661</id>
    <author>
      <name>github</name>
    </author>
    <dw:poster user="github"/>
    <link rel="alternate" type="text/html" href="https://changelog.dreamwidth.org/1922661.html"/>
    <link rel="self" type="text/xml" href="https://changelog.dreamwidth.org/data/atom/?itemid=1922661"/>
    <title>[dreamwidth/dreamwidth] 0d0dde: Bump github.com/aws/aws-sdk-go-v2/service/cloudwat...</title>
    <published>2026-04-08T01:41:00Z</published>
    <updated>2026-04-08T01:41:00Z</updated>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='github' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://github.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://github.dreamwidth.org/'&gt;&lt;b&gt;github&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Branch: refs/heads/dependabot/go_modules/src/dwtool/github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs-1.65.0
  Home:   https://github.com/dreamwidth/dreamwidth
  Commit: 0d0dde31d0f1e40afdb75a34408cfff9e453fd6c
      https://github.com/dreamwidth/dreamwidth/commit/0d0dde31d0f1e40afdb75a34408cfff9e453fd6c
  Author: dependabot[bot] &amp;lt;49699333+dependabot[bot]&lt;span style='white-space: nowrap;'&gt;&lt;a href='http://www.github.com/users/'&gt;&lt;img src='https://www.dreamwidth.org/img/profile_icons/github.png' alt='[github.com profile] ' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' width='16' height='16'/&gt;&lt;/a&gt;&lt;a href='http://www.github.com/users'&gt;&lt;b&gt;users&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&amp;gt;
  Date:   2026-04-08 (Wed, 08 Apr 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M src/dwtool/go.mod
    M src/dwtool/go.sum&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Bump github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs in /src/dwtool&lt;/p&gt;

&lt;p&gt;Bumps &lt;a href="https://github.com/aws/aws-sdk-go-v2"&gt;github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs&lt;/a&gt; from 1.63.1 to 1.65.0.
- &lt;a href="https://github.com/aws/aws-sdk-go-v2/releases"&gt;Release notes&lt;/a&gt;
- &lt;a href="https://github.com/aws/aws-sdk-go-v2/compare/service/s3/v1.63.1...service/s3/v1.65.0"&gt;Commits&lt;/a&gt;&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=changelog&amp;ditemid=1922661" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-06-03:11:1922540</id>
    <author>
      <name>github</name>
    </author>
    <dw:poster user="github"/>
    <link rel="alternate" type="text/html" href="https://changelog.dreamwidth.org/1922540.html"/>
    <link rel="self" type="text/xml" href="https://changelog.dreamwidth.org/data/atom/?itemid=1922540"/>
    <title>[dreamwidth/dreamwidth] fe8199: Fix flush-memcache to connect directly to each ser...</title>
    <published>2026-03-30T05:32:16Z</published>
    <updated>2026-03-30T05:32:16Z</updated>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='github' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://github.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://github.dreamwidth.org/'&gt;&lt;b&gt;github&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Branch: refs/heads/main
  Home:   https://github.com/dreamwidth/dreamwidth
  Commit: fe8199f3512e1daf0fb1c2bb999f4dc418ca5fb5
      https://github.com/dreamwidth/dreamwidth/commit/fe8199f3512e1daf0fb1c2bb999f4dc418ca5fb5
  Author: Mark Smith &lt;a href="mailto:mark@dreamwidth.org"&gt;&amp;#x6D;&amp;#97;&amp;#114;k&amp;#64;&amp;#100;&amp;#114;&amp;#101;&amp;#97;m&amp;#x77;&amp;#105;d&amp;#116;&amp;#x68;&amp;#46;&amp;#111;&amp;#x72;g&lt;/a&gt;
  Date:   2026-03-29 (Sun, 29 Mar 2026)&lt;/p&gt;

&lt;p&gt;Changed paths:
    M bin/flush-memcache&lt;/p&gt;

&lt;p&gt;Log Message:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Fix flush-memcache to connect directly to each server via IO::Socket::INET&lt;/p&gt;

&lt;p&gt;get_sock() expects a cache key, not a server address. Use IO::Socket::INET
to connect to each server directly and send flush_all.&lt;/p&gt;

&lt;p&gt;Co-Authored-By: Claude Opus 4.6 (1M context) &lt;a href="mailto:noreply@anthropic.com"&gt;&amp;#x6E;&amp;#111;&amp;#114;e&amp;#x70;&amp;#108;&amp;#121;&amp;#64;&amp;#97;&amp;#x6E;t&amp;#x68;&amp;#x72;&amp;#111;&amp;#112;&amp;#x69;&amp;#x63;.c&amp;#111;&amp;#109;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To unsubscribe from these emails, change your notification settings at https://github.com/dreamwidth/dreamwidth/settings/notifications&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=changelog&amp;ditemid=1922540" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
</feed>
