[{"id":"16949210475","type":"IssueCommentEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":5543112,"name":"lobsters/lobsters","url":"https://api.github.com/repos/lobsters/lobsters"},"payload":{"action":"created","issue":{"url":"https://api.github.com/repos/lobsters/lobsters/issues/2253","repository_url":"https://api.github.com/repos/lobsters/lobsters","labels_url":"https://api.github.com/repos/lobsters/lobsters/issues/2253/labels{/name}","comments_url":"https://api.github.com/repos/lobsters/lobsters/issues/2253/comments","events_url":"https://api.github.com/repos/lobsters/lobsters/issues/2253/events","html_url":"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/lobsters/lobsters/issues/2253","id":5802305380,"node_id":"I_kwDOAFSUyM8AAAABWdgnZA","number":2253,"title":"Sometimes mobile layout is broken by wide stories","user":{"login":"simonw","id":9599,"node_id":"MDQ6VXNlcjk1OTk=","avatar_url":"https://avatars.githubusercontent.com/u/9599?v=4","gravatar_id":"","url":"https://api.github.com/users/simonw","html_url":"/simonw","followers_url":"https://api.github.com/users/simonw/followers","following_url":"https://api.github.com/users/simonw/following{/other_user}","gists_url":"https://api.github.com/users/simonw/gists{/gist_id}","starred_url":"https://api.github.com/users/simonw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/simonw/subscriptions","organizations_url":"https://api.github.com/users/simonw/orgs","repos_url":"https://api.github.com/users/simonw/repos","events_url":"https://api.github.com/users/simonw/events{/privacy}","received_events_url":"https://api.github.com/users/simonw/received_events","type":"User","user_view_type":"public","site_admin":false},"labels":[],"state":"open","locked":false,"assignees":[],"milestone":null,"comments":1,"created_at":"2026-10-11T15:11:30Z","updated_at":"2026-10-11T15:19:47Z","closed_at":null,"assignee":null,"issue_field_values":[],"type":null,"active_lock_reason":null,"sub_issues_summary":{"total":0,"completed":0,"percent_completed":0},"issue_dependencies_summary":{"blocked_by":0,"total_blocked_by":0,"blocking":0,"total_blocking":0},"body":"See this screenshot of the homepage in mobile safari on an iPhone, caused by this story: https://lobste.rs/s/6vjx1k/how_shredding_json_is_giving_logfire\n\n<img width=\"1320\" height=\"1823\" alt=\"Image\" src=\"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/user-attachments/assets/3f925cf0-b4ac-4f25-9366-0e7b4dcbf85d\" />","reactions":{"url":"https://api.github.com/repos/lobsters/lobsters/issues/2253/reactions","total_count":0,"+1":0,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0},"timeline_url":"https://api.github.com/repos/lobsters/lobsters/issues/2253/timeline","performed_via_github_app":null,"state_reason":null,"pinned_comment":null},"comment":{"url":"https://api.github.com/repos/lobsters/lobsters/issues/comments/6110513186","html_url":"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/lobsters/lobsters/issues/2253#issuecomment-6110513186","issue_url":"https://api.github.com/repos/lobsters/lobsters/issues/2253","id":6110513186,"node_id":"IC_kwDOAFSUyM8AAAABbDcIIg","user":{"login":"simonw","id":9599,"node_id":"MDQ6VXNlcjk1OTk=","avatar_url":"https://avatars.githubusercontent.com/u/9599?v=4","gravatar_id":"","url":"https://api.github.com/users/simonw","html_url":"/simonw","followers_url":"https://api.github.com/users/simonw/followers","following_url":"https://api.github.com/users/simonw/following{/other_user}","gists_url":"https://api.github.com/users/simonw/gists{/gist_id}","starred_url":"https://api.github.com/users/simonw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/simonw/subscriptions","organizations_url":"https://api.github.com/users/simonw/orgs","repos_url":"https://api.github.com/users/simonw/repos","events_url":"https://api.github.com/users/simonw/events{/privacy}","received_events_url":"https://api.github.com/users/simonw/received_events","type":"User","user_view_type":"public","site_admin":false},"created_at":"2026-10-11T15:19:16Z","updated_at":"2026-10-11T15:19:47Z","body":"It happens here because the story details in the expandable area include long unbroken sequences. In this case I think that's:\n\n    ┌──────────────────────────────────────────┐\n\n\nRelevant code in the Lobste.rs CSS:\n\nhttps://github.com/lobsters/lobsters/blob/0d162b9cb010b5e3a54e2b3bfd3e80460254856d/app/assets/stylesheets/application.css#L542-L546\n\nChanging that to `overflow-wrap: anywhere;` should fix it.","pin":null,"reactions":{"url":"https://api.github.com/repos/lobsters/lobsters/issues/comments/6110513186/reactions","total_count":0,"+1":0,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0},"performed_via_github_app":null,"minimized":null}},"public":true,"created_at":"2026-10-11T15:19:16Z","org":{"id":32438445,"login":"lobsters","gravatar_id":"","url":"https://api.github.com/orgs/lobsters","avatar_url":"https://avatars.githubusercontent.com/u/32438445?"}},{"id":"16948898995","type":"IssuesEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":5543112,"name":"lobsters/lobsters","url":"https://api.github.com/repos/lobsters/lobsters"},"payload":{"action":"opened","issue":{"url":"https://api.github.com/repos/lobsters/lobsters/issues/2253","repository_url":"https://api.github.com/repos/lobsters/lobsters","labels_url":"https://api.github.com/repos/lobsters/lobsters/issues/2253/labels{/name}","comments_url":"https://api.github.com/repos/lobsters/lobsters/issues/2253/comments","events_url":"https://api.github.com/repos/lobsters/lobsters/issues/2253/events","html_url":"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/lobsters/lobsters/issues/2253","id":5802305380,"node_id":"I_kwDOAFSUyM8AAAABWdgnZA","number":2253,"title":"Sometimes mobile layout is broken by wide stories","user":{"login":"simonw","id":9599,"node_id":"MDQ6VXNlcjk1OTk=","avatar_url":"https://avatars.githubusercontent.com/u/9599?v=4","gravatar_id":"","url":"https://api.github.com/users/simonw","html_url":"/simonw","followers_url":"https://api.github.com/users/simonw/followers","following_url":"https://api.github.com/users/simonw/following{/other_user}","gists_url":"https://api.github.com/users/simonw/gists{/gist_id}","starred_url":"https://api.github.com/users/simonw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/simonw/subscriptions","organizations_url":"https://api.github.com/users/simonw/orgs","repos_url":"https://api.github.com/users/simonw/repos","events_url":"https://api.github.com/users/simonw/events{/privacy}","received_events_url":"https://api.github.com/users/simonw/received_events","type":"User","user_view_type":"public","site_admin":false},"labels":[],"state":"open","locked":false,"assignees":[],"milestone":null,"comments":1,"created_at":"2026-10-11T15:11:30Z","updated_at":"2026-10-11T15:19:47Z","closed_at":null,"assignee":null,"issue_field_values":[],"type":null,"active_lock_reason":null,"sub_issues_summary":{"total":0,"completed":0,"percent_completed":0},"issue_dependencies_summary":{"blocked_by":0,"total_blocked_by":0,"blocking":0,"total_blocking":0},"body":"See this screenshot of the homepage in mobile safari on an iPhone, caused by this story: https://lobste.rs/s/6vjx1k/how_shredding_json_is_giving_logfire\n\n<img width=\"1320\" height=\"1823\" alt=\"Image\" src=\"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/user-attachments/assets/3f925cf0-b4ac-4f25-9366-0e7b4dcbf85d\" />","reactions":{"url":"https://api.github.com/repos/lobsters/lobsters/issues/2253/reactions","total_count":0,"+1":0,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0},"timeline_url":"https://api.github.com/repos/lobsters/lobsters/issues/2253/timeline","performed_via_github_app":null,"state_reason":null,"pinned_comment":null}},"public":true,"created_at":"2026-10-11T15:11:31Z","org":{"id":32438445,"login":"lobsters","gravatar_id":"","url":"https://api.github.com/orgs/lobsters","avatar_url":"https://avatars.githubusercontent.com/u/32438445?"}},{"id":"23685705141","type":"PushEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":104670293,"name":"simonw/simonwillisonblog","url":"https://api.github.com/repos/simonw/simonwillisonblog"},"payload":{"repository_id":104670293,"push_id":46108055118,"ref":"refs/heads/main","head":"0d95e571c0f065b7818dd5a0b926a80d7d42b380","before":"e86bdf2ce6f75b3305c6cc3e2119a3b58c265cf5"},"public":true,"created_at":"2026-10-11T04:20:21Z"},{"id":"23675687455","type":"PushEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":104670293,"name":"simonw/simonwillisonblog","url":"https://api.github.com/repos/simonw/simonwillisonblog"},"payload":{"repository_id":104670293,"push_id":45976901814,"ref":"refs/heads/main","head":"e86bdf2ce6f75b3305c6cc3e2119a3b58c265cf5","before":"01b40e1493bb1a65e3f2a429f18c88acaee3afbf"},"public":true,"created_at":"2026-10-09T15:31:41Z"},{"id":"23656003862","type":"PushEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":140912432,"name":"simonw/sqlite-utils","url":"https://api.github.com/repos/simonw/sqlite-utils"},"payload":{"repository_id":140912432,"push_id":46096503107,"ref":"refs/heads/main","head":"9c66bafa52ae23d40499c74b0db3b635bcddb876","before":"6bc1d33d583c54bd69fbdd2071117e2d38c354a1"},"public":true,"created_at":"2026-10-11T00:15:55Z"},{"id":"16927479417","type":"PullRequestEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":104670293,"name":"simonw/simonwillisonblog","url":"https://api.github.com/repos/simonw/simonwillisonblog"},"payload":{"action":"merged","number":723,"pull_request":{"url":"https://api.github.com/repos/simonw/simonwillisonblog/pulls/723","id":4816522570,"number":723,"head":{"ref":"claude/fix-sponsor-banner-overflow","sha":"696a8f77f445beb6142626379a9d4cd69e283934","repo":{"id":104670293,"url":"https://api.github.com/repos/simonw/simonwillisonblog","name":"simonwillisonblog"}},"base":{"ref":"main","sha":"e86bdf2ce6f75b3305c6cc3e2119a3b58c265cf5","repo":{"id":104670293,"url":"https://api.github.com/repos/simonw/simonwillisonblog","name":"simonwillisonblog"}}}},"public":true,"created_at":"2026-10-11T04:20:20Z"},{"id":"16927440147","type":"PullRequestEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":104670293,"name":"simonw/simonwillisonblog","url":"https://api.github.com/repos/simonw/simonwillisonblog"},"payload":{"action":"opened","number":723,"pull_request":{"url":"https://api.github.com/repos/simonw/simonwillisonblog/pulls/723","id":4816522570,"number":723,"head":{"ref":"claude/fix-sponsor-banner-overflow","sha":"696a8f77f445beb6142626379a9d4cd69e283934","repo":{"id":104670293,"url":"https://api.github.com/repos/simonw/simonwillisonblog","name":"simonwillisonblog"}},"base":{"ref":"main","sha":"e86bdf2ce6f75b3305c6cc3e2119a3b58c265cf5","repo":{"id":104670293,"url":"https://api.github.com/repos/simonw/simonwillisonblog","name":"simonwillisonblog"}}}},"public":true,"created_at":"2026-10-11T04:18:55Z"},{"id":"23639932141","type":"CreateEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":752806463,"name":"simonw/pge-outages","url":"https://api.github.com/repos/simonw/pge-outages"},"payload":{"ref":"fix/validate-empty-outage-snapshots","ref_type":"branch","full_ref":"refs/heads/fix/validate-empty-outage-snapshots","master_branch":"main","description":"Tracking PG&E power outages","pusher_type":"user"},"public":true,"created_at":"2026-10-10T16:49:56Z"},{"id":"23630635015","type":"DeleteEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":622352364,"name":"simonw/llm","url":"https://api.github.com/repos/simonw/llm"},"payload":{"ref":"default-gpt-6-luna","ref_type":"branch","full_ref":"refs/heads/default-gpt-6-luna","pusher_type":"user"},"public":true,"created_at":"2026-10-09T06:59:29Z"},{"id":"23621318238","type":"PushEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":104670293,"name":"simonw/simonwillisonblog","url":"https://api.github.com/repos/simonw/simonwillisonblog"},"payload":{"repository_id":104670293,"push_id":45921546602,"ref":"refs/heads/codex/newsletters","head":"fc7516ae44bc389fdbd1ba64cace5aa0caadfdf7","before":"71fd266693d57da1a84ce47c319e0ffb48f48512"},"public":true,"created_at":"2026-10-09T03:58:52Z"},{"id":"23605298305","type":"PushEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":752806463,"name":"simonw/pge-outages","url":"https://api.github.com/repos/simonw/pge-outages"},"payload":{"repository_id":752806463,"push_id":46071108483,"ref":"refs/heads/main","head":"2264296b3730ebc3cf20aabc869468dec93c0b31","before":"ed1156543aeb730339d544acfba8478286b7f543"},"public":true,"created_at":"2026-10-10T16:50:43Z"},{"id":"16905082285","type":"PullRequestEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":752806463,"name":"simonw/pge-outages","url":"https://api.github.com/repos/simonw/pge-outages"},"payload":{"action":"merged","number":5,"pull_request":{"url":"https://api.github.com/repos/simonw/pge-outages/pulls/5","id":4812862769,"number":5,"head":{"ref":"fix/validate-empty-outage-snapshots","sha":"95606f14c9b84065b7370537c21a59f2cc0d3c01","repo":{"id":752806463,"url":"https://api.github.com/repos/simonw/pge-outages","name":"pge-outages"}},"base":{"ref":"main","sha":"ed1156543aeb730339d544acfba8478286b7f543","repo":{"id":752806463,"url":"https://api.github.com/repos/simonw/pge-outages","name":"pge-outages"}}}},"public":true,"created_at":"2026-10-10T16:50:41Z"},{"id":"16905062949","type":"PullRequestEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":752806463,"name":"simonw/pge-outages","url":"https://api.github.com/repos/simonw/pge-outages"},"payload":{"action":"opened","number":5,"pull_request":{"url":"https://api.github.com/repos/simonw/pge-outages/pulls/5","id":4812862769,"number":5,"head":{"ref":"fix/validate-empty-outage-snapshots","sha":"95606f14c9b84065b7370537c21a59f2cc0d3c01","repo":{"id":752806463,"url":"https://api.github.com/repos/simonw/pge-outages","name":"pge-outages"}},"base":{"ref":"main","sha":"ed1156543aeb730339d544acfba8478286b7f543","repo":{"id":752806463,"url":"https://api.github.com/repos/simonw/pge-outages","name":"pge-outages"}}}},"public":true,"created_at":"2026-10-10T16:50:15Z"},{"id":"23599253302","type":"PushEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":107914493,"name":"simonw/datasette","url":"https://api.github.com/repos/simonw/datasette"},"payload":{"repository_id":107914493,"push_id":45901720985,"ref":"refs/heads/claude-datasette-connection-spike","head":"6060a065b5a0caa3eed3d5fbc9868d089b0fe782","before":"c9e01076ea7594fb1c75d43afbd8c87354cf6b9c"},"public":true,"created_at":"2026-10-08T22:31:51Z"},{"id":"23591625398","type":"PushEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":104670293,"name":"simonw/simonwillisonblog","url":"https://api.github.com/repos/simonw/simonwillisonblog"},"payload":{"repository_id":104670293,"push_id":45922810159,"ref":"refs/heads/main","head":"0dc6acc7e0015bc6c92c93d944208feb3351706e","before":"55f0cdee9887c2bb204fa1dfaa1864d3fd90cc47"},"public":true,"created_at":"2026-10-09T04:19:24Z"},{"id":"23577157531","type":"CreateEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":140912432,"name":"simonw/sqlite-utils","url":"https://api.github.com/repos/simonw/sqlite-utils"},"payload":{"ref":"stable-3.15","ref_type":"branch","full_ref":"refs/heads/stable-3.15","master_branch":"main","description":"Python CLI utility and library for manipulating SQLite databases","pusher_type":"user"},"public":true,"created_at":"2026-10-09T15:13:43Z"},{"id":"23573047317","type":"PushEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":642509669,"name":"simonw/ttok","url":"https://api.github.com/repos/simonw/ttok"},"payload":{"repository_id":642509669,"push_id":45905589319,"ref":"refs/heads/main","head":"e8cdc8e594b50222f178c06e61eabcfbd34988f3","before":"f321073def1234911731a37f0d1e3dd4fa262da2"},"public":true,"created_at":"2026-10-08T23:30:50Z"},{"id":"23572700316","type":"PushEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":642509669,"name":"simonw/ttok","url":"https://api.github.com/repos/simonw/ttok"},"payload":{"repository_id":642509669,"push_id":45905261545,"ref":"refs/heads/main","head":"4ae479825d34f5f87117f4cb70342ed66c34d83c","before":"5a6ae1b7dc05a026085a25253fc27e2be5d5c0a2"},"public":true,"created_at":"2026-10-08T23:25:31Z"},{"id":"23572657566","type":"PushEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":642509669,"name":"simonw/ttok","url":"https://api.github.com/repos/simonw/ttok"},"payload":{"repository_id":642509669,"push_id":45905222139,"ref":"refs/heads/claude/wonderful-gates-vbg05r","head":"4f3e58729f09ca95ee9d66923c4079c77ac85717","before":"12f2f92a57b2756d037345e8c5d354b09e914f38"},"public":true,"created_at":"2026-10-08T23:24:54Z"},{"id":"23572233776","type":"PushEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":107914493,"name":"simonw/datasette","url":"https://api.github.com/repos/simonw/datasette"},"payload":{"repository_id":107914493,"push_id":45904831634,"ref":"refs/heads/claude-datasette-connection-spike","head":"8bf6e1964376fbaa7356812b7f608fa19680f90d","before":"0cf9920012c53b70f6c5e654a77ffe7732671f4c"},"public":true,"created_at":"2026-10-08T23:18:35Z"},{"id":"23557853083","type":"PushEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":779431605,"name":"simonw/tools","url":"https://api.github.com/repos/simonw/tools"},"payload":{"repository_id":779431605,"push_id":46027219461,"ref":"refs/heads/main","head":"89cd52d9e247bbe2ce654ae0fc11e506e26cbeba","before":"6bcbca4fe67102a7fc0672793856f92f76414d92"},"public":true,"created_at":"2026-10-10T03:37:37Z"},{"id":"23550722106","type":"PushEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":104670293,"name":"simonw/simonwillisonblog","url":"https://api.github.com/repos/simonw/simonwillisonblog"},"payload":{"repository_id":104670293,"push_id":45927320731,"ref":"refs/heads/main","head":"35c592714bb7b4b9cb75b42d8a2f7db4354f3299","before":"686a55287388bdb1acf70458f1a4fcb94885f1c2"},"public":true,"created_at":"2026-10-09T05:33:49Z"},{"id":"23549645315","type":"PushEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":104670293,"name":"simonw/simonwillisonblog","url":"https://api.github.com/repos/simonw/simonwillisonblog"},"payload":{"repository_id":104670293,"push_id":45929558502,"ref":"refs/heads/main","head":"9331d82481c041833b0277db07ee2a719a1c7707","before":"35c592714bb7b4b9cb75b42d8a2f7db4354f3299"},"public":true,"created_at":"2026-10-09T06:08:34Z"},{"id":"23547451576","type":"PushEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":104670293,"name":"simonw/simonwillisonblog","url":"https://api.github.com/repos/simonw/simonwillisonblog"},"payload":{"repository_id":104670293,"push_id":45922385081,"ref":"refs/heads/codex/newsletters","head":"afc5f900658432ca79b5b4080fdf3a9653252747","before":"059c702573fa5465d668644365c35286858056bd"},"public":true,"created_at":"2026-10-09T04:12:12Z"},{"id":"23545794747","type":"PushEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":1219599644,"name":"simonw/monthly-newsletter-archive","url":"https://api.github.com/repos/simonw/monthly-newsletter-archive"},"payload":{"repository_id":1219599644,"push_id":45919849302,"ref":"refs/heads/main","head":"dcfb4cabdde97b5899f3586be7d6a13efd32a947","before":"20790d50ab9753952978ecafdec9ef1651b9eae2"},"public":true,"created_at":"2026-10-09T03:29:55Z"},{"id":"23545763567","type":"PushEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":104670293,"name":"simonw/simonwillisonblog","url":"https://api.github.com/repos/simonw/simonwillisonblog"},"payload":{"repository_id":104670293,"push_id":45923705869,"ref":"refs/heads/main","head":"686a55287388bdb1acf70458f1a4fcb94885f1c2","before":"463eafc59807a346434151424c357780d118bf31"},"public":true,"created_at":"2026-10-09T04:34:33Z"},{"id":"23545392041","type":"PushEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":104670293,"name":"simonw/simonwillisonblog","url":"https://api.github.com/repos/simonw/simonwillisonblog"},"payload":{"repository_id":104670293,"push_id":45919251047,"ref":"refs/heads/codex/newsletters","head":"1698595dc38cb2fdeb70ce0a3836dfdfd82ca24a","before":"56c7275e0ed87570db2ea347c56ab332afc340e5"},"public":true,"created_at":"2026-10-09T03:19:41Z"},{"id":"23529085709","type":"PushEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":107914493,"name":"simonw/datasette","url":"https://api.github.com/repos/simonw/datasette"},"payload":{"repository_id":107914493,"push_id":45902022789,"ref":"refs/heads/claude-datasette-connection-spike","head":"2e4bc5bed070a1069a139527bcb6649072aa1b39","before":"162029b98fce65623d07e1cb8561a5ae80a776b6"},"public":true,"created_at":"2026-10-08T22:36:11Z"},{"id":"16869296272","type":"IssueCommentEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":104670293,"name":"simonw/simonwillisonblog","url":"https://api.github.com/repos/simonw/simonwillisonblog"},"payload":{"action":"created","issue":{"url":"https://api.github.com/repos/simonw/simonwillisonblog/issues/721","repository_url":"https://api.github.com/repos/simonw/simonwillisonblog","labels_url":"https://api.github.com/repos/simonw/simonwillisonblog/issues/721/labels{/name}","comments_url":"https://api.github.com/repos/simonw/simonwillisonblog/issues/721/comments","events_url":"https://api.github.com/repos/simonw/simonwillisonblog/issues/721/events","html_url":"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/simonw/simonwillisonblog/pull/721","id":5780886854,"node_id":"PR_kwDOBj0kVc8AAAABHkPe7Q","number":721,"title":"Switch tests to use pytest-django","user":{"login":"simonw","id":9599,"node_id":"MDQ6VXNlcjk1OTk=","avatar_url":"https://avatars.githubusercontent.com/u/9599?v=4","gravatar_id":"","url":"https://api.github.com/users/simonw","html_url":"/simonw","followers_url":"https://api.github.com/users/simonw/followers","following_url":"https://api.github.com/users/simonw/following{/other_user}","gists_url":"https://api.github.com/users/simonw/gists{/gist_id}","starred_url":"https://api.github.com/users/simonw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/simonw/subscriptions","organizations_url":"https://api.github.com/users/simonw/orgs","repos_url":"https://api.github.com/users/simonw/repos","events_url":"https://api.github.com/users/simonw/events{/privacy}","received_events_url":"https://api.github.com/users/simonw/received_events","type":"User","user_view_type":"public","site_admin":false},"labels":[{"id":701577817,"node_id":"MDU6TGFiZWw3MDE1Nzc4MTc=","url":"https://api.github.com/repos/simonw/simonwillisonblog/labels/enhancement","name":"enhancement","color":"84b6eb","default":true,"description":null,"archived_at":null,"archived_by":null}],"state":"open","locked":false,"assignees":[],"milestone":null,"comments":1,"created_at":"2026-10-09T15:51:23Z","updated_at":"2026-10-09T15:57:55Z","closed_at":null,"assignee":null,"active_lock_reason":null,"draft":false,"pull_request":{"url":"https://api.github.com/repos/simonw/simonwillisonblog/pulls/721","html_url":"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/simonw/simonwillisonblog/pull/721","diff_url":"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/simonw/simonwillisonblog/pull/721.diff","patch_url":"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/simonw/simonwillisonblog/pull/721.patch","merged_at":null},"body":"Tests were getting *really* slow. On `main` right now running `just` takes between 80 and 260 seconds:\r\n\r\n    Ran 453 tests in 261.815s\r\n\r\nSwitching to running tests in `pytest` with fixtures speeds that up to:\r\n\r\n    463 passed in 7.87s\r\n\r\nGPT-6 Astra High: https://gist.github.com/simonw/7d37b72da098f24241119f5d7d97318d\r\n\r\n> Why is running tests so slow?\r\n\r\n> Port the tests to use Django pytest and add fixtures that help avoid those problems","reactions":{"url":"https://api.github.com/repos/simonw/simonwillisonblog/issues/721/reactions","total_count":0,"+1":0,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0},"timeline_url":"https://api.github.com/repos/simonw/simonwillisonblog/issues/721/timeline","performed_via_github_app":null,"state_reason":null},"comment":{"url":"https://api.github.com/repos/simonw/simonwillisonblog/issues/comments/6084464377","html_url":"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/simonw/simonwillisonblog/pull/721#issuecomment-6084464377","issue_url":"https://api.github.com/repos/simonw/simonwillisonblog/issues/721","id":6084464377,"node_id":"IC_kwDOBj0kVc8AAAABaqmO-Q","user":{"login":"simonw","id":9599,"node_id":"MDQ6VXNlcjk1OTk=","avatar_url":"https://avatars.githubusercontent.com/u/9599?v=4","gravatar_id":"","url":"https://api.github.com/users/simonw","html_url":"/simonw","followers_url":"https://api.github.com/users/simonw/followers","following_url":"https://api.github.com/users/simonw/following{/other_user}","gists_url":"https://api.github.com/users/simonw/gists{/gist_id}","starred_url":"https://api.github.com/users/simonw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/simonw/subscriptions","organizations_url":"https://api.github.com/users/simonw/orgs","repos_url":"https://api.github.com/users/simonw/repos","events_url":"https://api.github.com/users/simonw/events{/privacy}","received_events_url":"https://api.github.com/users/simonw/received_events","type":"User","user_view_type":"public","site_admin":false},"created_at":"2026-10-09T15:57:55Z","updated_at":"2026-10-09T15:57:55Z","body":"I ran a review with Opus 5.5:\r\n\r\n    llm -f https://patch-diff.githubusercontent.com/raw/simonw/simonwillisonblog/pull/721.diff \\\r\n      -s 'review this diff' -m claude-opus-5.5\r\n\r\n<details><summary>Review</summary>\r\n\r\n# Review: migrate test suite from Django `TestCase` to pytest-django\r\n\r\nThis is a solid migration. Most of it is a mechanical assertion rewrite. The substantive changes are:\r\n\r\n- **`TransactionTestCase` → `@pytest.mark.django_db`.** Tests now roll back instead of flushing, which should be a big speedup for `blog/tests.py`.\r\n- **A `commit_callbacks` fixture.** It replaces the implicit \"real commits fire `on_commit`\" behaviour.\r\n- **A session-wide `fast_test_settings` fixture.** It speeds up password hashing and drops static-file serving.\r\n- **Runner changes.** CI, the shell scripts and the Justfile now use `uv run … pytest`.\r\n\r\nThe direction is good. Below are the things I'd look at before merging, roughly in priority order.\r\n\r\n## Worth addressing\r\n\r\n### 1. Tests no longer catch broken `{% static %}` references\r\n\r\n`fast_test_settings` does two things:\r\n- It swaps the staticfiles backend to plain `StaticFilesStorage`.\r\n- It removes WhiteNoise.\r\n\r\nProduction presumably uses a manifest storage. With manifest storage, a template referencing a non-existent static file raises at render time and becomes a 500. Under the test settings, `static()` just concatenates a URL, so that bug now passes the suite.\r\n\r\nCI's `collectstatic` step doesn't cover this. It verifies that collection works, not that every template reference resolves.\r\n\r\nOptions:\r\n- Keep the manifest backend in one or two smoke tests (homepage, entry, admin index) via the `settings` fixture, after a session-scoped `collectstatic` into a tmp dir.\r\n- At minimum, note the trade-off in AGENTS.md. It currently presents the change as purely a speed-up.\r\n\r\n### 2. Silent loss of `on_commit` side effects in other tests\r\n\r\nPreviously every `blog` test was a `TransactionTestCase`, so search indexing ran for free. You've added `commit_callbacks()` where search assertions exist:\r\n- `test_draft_items_not_displayed`\r\n- `test_id_filter_combined_with_search_query`\r\n- `test_beat_subtype_with_search_query`\r\n- the chapter search tests\r\n\r\nAny test that only asserts loosely won't fail; it will just stop testing what it used to. For example, `TestTypeListing.test_search_within_type` only checks for a 200.\r\n\r\nIt's worth grepping for `q=` / `SearchQuery` usages in tests and confirming each has either `commit_callbacks` or doesn't depend on the index. Also check for any non-search `on_commit` hooks (cache purges, etc.) that tests implicitly relied on.\r\n\r\n### 3. `CLAUDE.md` contradicts itself\r\n\r\nThe prerequisites section above the edited hunk still says:\r\n\r\n> This project uses Django's built-in test framework with PostgreSQL.\r\n> 3. Dependencies installed: `pip install -r requirements.txt`\r\n\r\nBoth statements conflict with the new \"use `uv run`, don't create a venv\" guidance a few lines later. Please update or remove them.\r\n\r\n### 4. CI caching no longer does anything\r\n\r\n`actions/setup-python` with `cache: pip` now only caches the `uv` wheel. Meanwhile `uv run --with-requirements` resolves and installs into uv's cache (`~/.cache/uv`), which isn't persisted between runs. Consider replacing the install step with `astral-sh/setup-uv` with `enable-cache: true`.\r\n\r\nMinor: the three `uv run --with-requirements requirements.txt` invocations could share a `UV_RUN` env var, or the job could use `just`.\r\n\r\n### 5. `DATABASE_URL` for `just`\r\n\r\nAGENTS.md now says just run `just`, and drops the note that the URL lives in `.claude/settings.json`. If the Justfile (lines 1–4, not shown) doesn't export `DATABASE_URL`, `just` will fail for anyone without it in their environment. If it does export it, fine; otherwise restore the note or add `set dotenv-load` / an `export`.\r\n\r\n## Minor / nits\r\n\r\n- **`--reuse-db` wording.** Django's `keepdb` path still runs `migrate`, so new migrations are applied automatically. `--create-db` is really only needed when an existing migration is edited or you switch branches. The docs (\"pass `--create-db` after schema changes\") slightly overstate it, which is harmless but may cause confusion.\r\n\r\n- **pytest 9 dependency.** The `subtests` fixture is built into pytest ≥ 9, so this relies on the `pytest==9.1.1` pin. A comment in `requirements.txt` or a `minversion = 9.0` line in `pytest.ini` would make that explicit.\r\n\r\n- **Repeated client boilerplate.** Many classes repeat:\r\n  ```python\r\n  @pytest.fixture(autouse=True)\r\n  def setup(self, client):\r\n      self.client = client\r\n  ```\r\n  This is fine as a transitional step. Longer-term, request `client` as a test argument directly; that's more idiomatic and drops the per-class fixture.\r\n\r\n- **Mechanical-conversion artifacts:**\r\n  - `assert all((x for x in ...))` / `assert not any((...))`: the double parentheses can go.\r\n  - Yoda comparisons in `feedstats/tests.py` (`assert 0 == SubscriberCount.objects.count()`) read better flipped.\r\n  - In `test_create_live_update`, the expected HTML was collapsed from a readable implicit concatenation into a single ~250-character line. I'd restore the multi-line form.\r\n\r\n- **`test_section_unique_together`.** This works because nothing queries after the `IntegrityError`. If someone later adds an assertion after the `pytest.raises`, it will hit \"current transaction is aborted\". Wrapping the factory call in `transaction.atomic()` inside the `raises` block makes it robust.\r\n\r\n- **`override_settings` in `test_admin_purge_calls_sdk_and_flashes_success`.** This could use the `settings` fixture for consistency with `TestPrivateMonthlyApi`. Not required.\r\n\r\n- **`GuideSection` import removed from `blog/tests.py`.** It looks unused (only the factory is referenced), but confirm there's no stray usage.\r\n\r\n- **`config/urls.py` favicon change.** It's a good fix (closes the file handle) but unrelated. Fine to keep; just mention it in the PR description.\r\n\r\n## Looks good\r\n\r\n- **`commit_callbacks`** is a nice design: it is explicit, respects savepoint rollback, and `test_indexing.py` pins down all three behaviours (deferred, discarded on rollback, real commit).\r\n- **Moving `TestFirstThreeParagraphs`, `TestCharDiffHtml` and `TestBuildDiffHtml` off the DB entirely** is a free speedup.\r\n- **Fixtures that create rows request `db` explicitly**, which avoids the autouse-ordering pitfall with class-level marks.\r\n- **Class-level `@override_settings` was correctly replaced** with the `settings` fixture, since the decorator only works on `SimpleTestCase` subclasses. Method-level `@override_settings` still works on plain functions because pytest follows `__wrapped__`.\r\n- **Adding `shortener` to `testpaths`** fixes a gap: the old Justfile didn't run those tests.\r\n\r\n</details>","reactions":{"url":"https://api.github.com/repos/simonw/simonwillisonblog/issues/comments/6084464377/reactions","total_count":0,"+1":0,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0},"performed_via_github_app":null,"minimized":null}},"public":true,"created_at":"2026-10-09T15:57:55Z"},{"id":"23509803944","type":"CreateEvent","actor":{"id":9599,"login":"simonw","display_login":"simonw","gravatar_id":"","url":"https://api.github.com/users/simonw","avatar_url":"https://avatars.githubusercontent.com/u/9599?"},"repo":{"id":104670293,"name":"simonw/simonwillisonblog","url":"https://api.github.com/repos/simonw/simonwillisonblog"},"payload":{"ref":"pytest-django","ref_type":"branch","full_ref":"refs/heads/pytest-django","master_branch":"main","description":"The source code behind my blog","pusher_type":"user"},"public":true,"created_at":"2026-10-09T15:46:06Z"}]