- β
- β
- September 18, 2026
-
π New Music Releases O.A.R. - Three Tinted Windows rss
O.A.R. - a new release is available:
- 2026-09-18: Three Tinted Windows (Album)
Amazon: Canada | Deutschland | France | United Kingdom | United States
Visit muspy for more information.
-
- September 17, 2026
-
π anthropics/claude-code v2.1.275 release
What's changed
- Added the signed-in account to Claude apps gateway sign-in: when the gateway names it, you confirm it before the credential is saved, and
/statusshows it - Added a send-now key (ctrl+enter, or ctrl+x ctrl+s) that interrupts the current turn and sends all queued messages at once; sent and queued messages show in gray until the model receives them
- Added a startup warning when a configured
otelHeadersHelperfails, so sessions that silently export no telemetry are noticed - Added syncing of the skills and plugins enabled on your claude.ai account to terminal sessions signed in with it; opt out with
syncClaudeAiSkills: falseorsyncClaudeAiPlugins: false - Added
/plugin install <plugin> --marketplace <source>, which offers to add the marketplace before installing the plugin - Fixed a restored memory file's age note changing between requests after a compaction or resume, which caused prompt cache misses
- Fixed
--forward-subagent-textstream-json and SDK output dropping the messages of subagents spawned by acontext: forkskill, and of forked skills invoked by a subagent or another forked skill - Fixed @-mention file suggestions being buried below MCP resources when using a custom
fileSuggestioncommand or typing@./@./ - Fixed fullscreen mode placing background-task completion notices beneath a long turn's collapsed tool row instead of where they arrived; each notice now closes the open row
- Fixed
claude plugin marketplace updatedeleting a GitHub marketplace's local copy when the fetch failed and the marketplace was named after its repository - Fixed plugin and marketplace messages, logs and
claude plugin marketplace listshowing a password or token stored in a git, ssh or marketplace URL - Fixed a resumed cloud session leaving an unanswered question open in the transcript after a queued message superseded it
- Fixed vim mode placing the cursor one character right after a dot-repeated "!" or a fast-typed "i!" switched a non-empty prompt into shell mode
- Fixed fullscreen mode freezing or blanking for several seconds when scrolling up past a large file diff
- Fixed a stray
</ccmemory>-style closing tag occasionally appearing in responses - Fixed plugin messages, logs and the VS Code plugin dialog showing the wrong server for some git addresses
- Fixed a terminal
API Error: 400on every turn for users behind a network gateway that rewrites API error responses when a beta request header is rejected - Fixed sandboxed Bash commands on Linux reporting exit code 0 for failed commands when the shell is zsh
- Fixed the Read tool hanging instead of reporting an error when part of a large file could not be decoded under memory pressure
- Fixed
--resume, the resume picker preview, resumed background agents and the transcript view failing on a session whose saved history contains a malformed task-reminder or @-file attachment entry - Fixed a crash when resuming a conversation whose transcript contains a malformed message entry, and a fullscreen crash when such a conversation received new messages while scrolled up
- Fixed sessions failing to resume or start when their saved transcript contains a malformed message content block
- Fixed Grep, Glob and @-file suggestions hanging or running out of memory on searches over the 20MB output cap, and system ripgrep reporting "no matches" instead of an error after a flood of warnings
- Fixed
/rewindin a forked or background session restoring a zero-filled or truncated file when the session's file-history backups could not be fully copied - Fixed fullscreen sessions sometimes exiting with "Claude Code exited after an unrecoverable interface error" when typing fast or holding a key with the slash-command dropdown open
- Fixed background sessions crashing and restarting their worker when a command fed through stdin ran on a machine that had run out of file descriptors
- Fixed a crash at launch when
~/.claude.jsonholds a malformedmcpNeedsAuthNoticedvalue - Fixed
--resumeand--continuedropping a conversation's earlier thinking when a built-in tool it started with has since been switched off by a server-side flag - Fixed text selected with the mouse in the fullscreen
claude --resumesession picker never reaching the clipboard - Fixed plugin reload previews replacing a running session's extracted plugin files when the plugin was loaded from a
--plugin-diror--plugin-urlarchive - Fixed self-hosted runners with
--drain-wait-seclosing the final result of a turn that finished during a SIGTERM drain; the runner now waits briefly for the turn to be reported - Fixed
SubagentStophooks with a specificmatcherfiring for every stopping subagent whose agent type was empty - Fixed sandboxed Bash commands being unable to write to project directories named
hooks/orconfig/ - Fixed Artifact updates failing with "File not found" after a session resumes on another machine or its scratchpad is cleared: the page's last published version is restored
- Fixed
/update-configwritingWrite(path)permission rules, which file permission checks don't match, instead ofEdit(path)rules - Fixed four dead documentation URLs (Pricing, Computer Use, Skills, CLI) in the bundled claude-api skill's live-sources table
- Improved prompt caching for a
--system-promptthat contains a__SYSTEM_PROMPT_DYNAMIC_BOUNDARY__line: the text above it is now cached globally, as the SDK's array form already is - Improved the
/desktoperror when Claude Desktop does not open: it now says why and what to do next - Improved the Artifact tool's publish and read results: they now say who can open the page and what the owner's Share menu offers
- Improved artifact publish results: they name the tab icon sent, warn when the page contains a NUL byte, and retry a flaky fetch of the newer page to merge after a stale publish
- Improved pasted and attached images: they are now saved where Claude can open them as files without a permission prompt, including in Desktop and VS Code
- Improved the Artifact tool's guidance so Claude updates a shared artifact in place when you were given edit access to it, instead of publishing a separate copy
- Improved plan-usage reads: editor windows and non-interactive sessions on one machine now share a read made in the last minute instead of each calling the usage endpoint
- Improved the
ListPluginstool description so Claude knows it lists plugins enabled on your claude.ai account, not plugins installed locally with/plugin - Improved responsiveness when the terminal is slow or paused: output no longer falls further behind while the terminal catches up
- Improved Write and Edit results for files in the synced account-skills folder: they now say the change is not saved to your account and how to save it
- Updated
/logoutfor Claude apps gateway sign-ins to also end the session on gateways that advertise token revocation - Changed hosted sessions to keep an unanswered permission prompt up after a container restart, instead of asking again
- Changed the Artifact tool to ask for a one-word tab icon on a first publish instead of an emoji favicon
- Changed Claude in Chrome in auto mode to skip the extension's per-site check for classifier-approved calls, as bypass mode does, fixing
browser_batch"Permission denied" after a redirect - Changed plugins installed from an npm source to be fetched with
npm pack --ignore-scriptsand integrity-verified, so a package's install scripts no longer run - Changed scheduled and Run now routine runs to save data to, and republish the page of, an artifact you can edit without asking; public artifacts, first publishes and deletes still ask
- Removed the startup notice that told you a one-off scheduled routine had run since your last session
- [VSCode] Added viewing, editing and deleting a saved memory inside the Memory dialog
- [VSCode] Added sending an attached image without typing any text
- [VSCode] Added a Retry link to the MCP servers dialog when the server list fails to load
- [VSCode] Added accept and reject buttons under each change in the proposed-change diff tab, so an edit can be reviewed change by change
- [VSCode] Fixed the transcript creeping toward the bottom in small steps while a permission card waits and content keeps arriving
- [VSCode] Fixed rewound and forked conversations not keeping the permission mode you had picked for the original conversation
- [VSCode] Fixed an empty
CLAUDE_CONFIG_DIRentry in theenvironmentVariablessetting making Claude Code keep its files in the workspace - [VSCode] Fixed plugin install links opening the Manage plugins dialog for plugin names and marketplace addresses that can't be used in a link
- [VSCode] Fixed Remote Control staying shown as connected after a turn-off that Claude Code reported as failed; it now shows as off
- [VSCode] Fixed the scroll to the bottom on send stopping short of the reply when the reply starts arriving during the scroll
- [VSCode] Fixed the agent map showing agents a crash left unfinished as stopped instead of failed once the session is reopened
- [VSCode] Fixed the "Continuing the step" notice not appearing, and the continue limit resetting, after a reload that follows a crash with background tasks still running
- [VSCode] Fixed the session list showing when a session was last reopened, such as after a window reload, instead of when its last message was sent
- [VSCode] Fixed "Fork conversation from here" failing on the message right after one sent while Claude was working
- [VSCode] Fixed the prompt cache clock showing too few minutes after reopening a session with a message sent while Claude was working
- [VSCode] Fixed a background agent that finished while Claude was running a tool losing its completion notice, and its result on the agent map, after a window reload
- [VSCode] Fixed a rare case where text selected in a git-ignored file could be sent to Claude after the extension was unresponsive for several seconds
- [VSCode] Fixed renaming a running session reverting to the generated name (regression in 2.1.269)
- [VSCode] Fixed some claude.ai/code sessions opening in VS Code as an empty conversation with no messages
- [VSCode] Fixed slash commands typed while Claude is responding being sent to the model as text instead of running once the response finishes
- [VSCode] Fixed unreadable code in the plan preview and the Hooks and Permission rules dialogs with the High Contrast Light theme
- [VSCode] Fixed
/remote-controlbeing ignored while Remote Control is still connecting: running it again now turns Remote Control off immediately - [VSCode] Fixed the conversation pulling you back to the bottom while a reply streams after you scroll up, and added a
claudeCode.scrollToBottomOnSendsetting to turn off the jump on send - [VSCode] Fixed the Manage plugins dialog showing a password or token that was typed into a marketplace URL
- [VSCode] Improved the agent map: the pill counts running agents and turns red after a failure, the main agent stays in view while the map scrolls, and agents sort by state then end time
- [VSCode] Changed New session in a Claude editor tab to open in the sidebar when Preferred Location is set to Sidebar, instead of always opening another tab
- [VSCode] Changed a message sent while Claude is working to wait at the bottom of the conversation until Claude starts on it
- [Claude Code on the web] Added a "New routine" button to the page shown when a routine link no longer resolves, next to the link back to your routines list
- [Claude Code on the web] Fixed routine "paused" and "on hold" notifications being cut off mid-sentence; the paused-subscription notice now says to turn the routine back on yourself
- [Claude Code on the web] Fixed cloud environments with a very long allowed-domains list saving fine and then failing every session start; saving now fails up front and says how much to trim
- [Claude Code on the web] Fixed Claude's guidance when a cloud session on a personal account is denied GitHub access: it now links to claude.ai/connect-github instead of an admin settings page
- [Claude Code on the web] Improved what Claude tells you when asked to edit, delete or run a routine it didn't create: it now links to the routine's page so you can do it yourself
- [Claude Tag] Added attach conditions for access bundles in Claude Tag settings: an Owner can let a bundle also apply in channels with guests or Slack Connect channels, not just member-only
- [Claude Tag] Added Amazon CloudWatch, CloudWatch Logs, Amazon SNS, Google Cloud Monitoring and Cloud Logging presets to an access bundle's Credentials tab in Claude Tag admin settings
- [Claude Tag] Added Datadog presets for the US3, AP1, AP2 and US1-FED sites; new Datadog connections are now limited to Datadog's read and query API routes
- [Claude Tag] Fixed S3 uploads from recent AWS CLI and SDK versions failing with a 502 error when sent through an AWS connection
- [Claude Tag] Fixed Claude treating a channel as inactive, and skipping untagged messages there, while it was still posting in that channel from a routine or a thread
- [Claude Tag] Fixed a thread's "Claude [task]" display name reverting to plain "Claude" after the session behind that thread was refreshed or restarted
- [Claude Tag] Fixed the model you switched to in a Slack thread silently reverting to the channel's default after that thread's session was restarted or refreshed
- [Claude Tag] Fixed Claude sometimes replying twice when another app or bot @mentioned it in a top-level channel message
- [Claude Tag] Improved Claude's notices in Enterprise Grid channels shared across workspaces: they now say when no workspace is set up yet, or why only organization defaults apply
- [Code Review] Fixed reviews occasionally dropping part of their analysis when one of the reviewing agents returned its findings in an unexpected format
- [Code Review] Fixed pull requests with more than 100 Claude reviews getting a full re-review on every clean merge from the base branch instead of the lighter merge-focused review
- Added the signed-in account to Claude apps gateway sign-in: when the gateway names it, you confirm it before the credential is saved, and
-
π r/LocalLLaMA Thank you :) Swift Qwen 3.8 27B now has 100k+ downloads, is #1 finetune and #9 model on HuggingFace Trending rss
| Hey everyone, Jovan from UkisAI here, a small lab building the tech to make tiny frontier LLMs possible (and doing it open-source!) The purpose of this post is simply to thank the community for all the amazing finetunes, quantizations and overall improvements over our original release which made our model get attention and the support for us to continue building in this direction! If it weren't for you guys going out of the way to contribute we wouldn't have half the results of this. For context: Swift Qwen 3.8 27B is our first open-source model release. It is proof of how penalizing pathological overthinking patterns inside of small LLMs can bring their token usage down -58.3% and speed x1.95 without losing accuracy by not training them to think shorter directly but rather to think more efficiently. We are continuing to build and are about to drop: - Swift1.5 Qwen3.8 27B (an improved checkpoint of the model with some training bugs fixed and more RL) - Swift Qwen3.8 Flash Next in the upcoming week week, we are now running the benchmark suite to not give out premature or incomplete results. This time we ran even more benchmarks as you guys suggested, including more coding and long horizon! It would be amazing if those of you who tried Swift would let us know what quants, features, changes you want to see in our upcoming model releases so we can do it better this time as we didn't even think about half of the stuff you guys were requesting last time :) Let the era of non-slop finetunes begin! EDIT: Links - https://huggingface.co/ukisai/Swift-Qwen3.8-27b https://huggingface.co/ukisai/Swift-Qwen3.8-27B-GGUF https://huggingface.co/bartowski/ukisai_Swift-Qwen3.8-27b-GGUF submitted by /u/Secure_Recording_472
[link] [comments]
---|--- -
π HexRaysSA/plugin-repository commits sync repo: +4 releases, -4 releases rss
sync repo: +4 releases, -4 releases ## New releases - [ida-mcp](https://github.com/hexrayssa/ida-mcp): 2026.917.2, 2026.917.1 - [ida-nexus](https://github.com/hexrayssa/ida-nexus): 0.12.2, 0.12.1 ## Changes - [ida-codemode](https://github.com/hexrayssa/ida-codemode): - removed version(s): 0.5.2, 0.5.1, 0.5.0, 0.4.1 -
π r/LocalLLaMA I literally built the Jev architecture one year back and completely open-sourced it with model, dataset and paper rss
Everyone now talks about the architecture that's not auto regressive and does lightning fast probability prediction with a json schema. I worked on this literally one year back in March 2025, published an arxiv paper, pushed the model to huggingface along with the pypi package and training dataset. And then one year later, a
frontier lab came, proposing the same idea like literal breakthrough without technical papers, open weights and no open dataset. I posted my approach in this subreddit. For anyones information the main guiding model is RL not embedding model or LLM
Reddit post: https://www.reddit.com/r/LocalLLaMA/s/6eGEwsAz43
Paper: https://arxiv.org/abs/2503.23303
Model: https://huggingface.co/DeepMostInnovations/sales-conversion-model- reinf-learning
Dataset: https://huggingface.co/datasets/DeepMostInnovations/saas-sales- conversations
Also the second work published in September 2025 was exactly the same one jev proposed now
Paper: https://arxiv.org/abs/2510.01237
My model uses PPO over sequence embeddings to output turn-by-turn conversion trajectories (probabilities from 0.0 to 1.0).
Jev uses parallel sampling (trained via RLCD) to output confidence distributions and schema choices.
It's incredibly frustrating that the thing that you made with months of hard work, sweat and sleepless night is architecturally similar with the vertical use case and don't get the support you deserve because frontier lab build something horizontal. The open-source story in general π
Previous post deleted by reddit filters btw
submitted by /u/Nandakishor_ml
[link] [comments] -
π r/LocalLLaMA I literally built the Jev architecture one year back and completely open-sourced it with model, dataset and paper rss
Everyone now talks about the architecture that's not auto regressive and does lightning fast probability prediction with a json schema. I worked on this literally one year back in March 2025, published an arxiv paper, pushed the model to huggingface along with the pypi package and training dataset. And then one year later, a
frontier lab came, proposing the same idea like literal breakthrough without technical papers, open weights and no open dataset. I posted my approach in this subreddit. Links are. For anyones information the main guiding model is RL not embedding model or LLM
Reddit post: https://www.reddit.com/r/LocalLLaMA/s/6eGEwsAz43
Paper: https://arxiv.org/abs/2503.23303
Model: https://huggingface.co/DeepMostInnovations/sales-conversion-model- reinf-learning
Dataset: https://huggingface.co/datasets/DeepMostInnovations/saas-sales- conversations
Also the second work published in September 2025 was exactly the same one jev proposed now
Paper: https://arxiv.org/abs/2510.01237
My model uses PPO over sequence embeddings to output turn-by-turn conversion trajectories (probabilities from 0.0 to 1.0).
Jev uses parallel sampling (trained via RLCD) to output confidence distributions and schema choices.
It's incredibly frustrating that the thing that you made with months of hard work, sweat and sleepless night is architecturally similar with the vertical use case and don't get the support you deserve because frontier lab build something horizontal. The open-source story in general π
submitted by /u/Nandakishor_ml
[link] [comments] -
π anthropics/claude-code v2.1.274 release
What's changed
- Added a visible warning when memory usage is critical, with steps to free memory or restart safely
- Added
CLAUDE_CODE_MCP_STARTUP_WAIT_MSto bound how long the first non-interactive turn waits for connecting MCP servers (0= don't wait) - Added
effortattribute to theclaude_code.llm_requestOpenTelemetry trace span, matching theapi_requestevent - Added
claude_code.managed_settings_resolvedOTel event: managed-settings sources and policy helper state; redacted settings and digests withOTEL_LOG_MANAGED_SETTINGS=1 - Added
store.connect_timeout_secondsto the Claude apps gateway config to lengthen the Postgres connect timeout (default 5 seconds), and improved the boot error when the database is unreachable to point tostore.postgres_urland the configured timeout - Added
enduser.sub, the IdP subject, to the telemetry Claude Desktop and Cowork send through a Claude apps gateway - Added a Claude apps gateway warning when a replica has more requests open than the 256 it sends upstream at once, and a startup log line showing that limit
- Added click-to-expand for collapsed teammate and agent messages in fullscreen mode
- Fixed sessions getting stuck endlessly retrying "unexpected tool_use_id" 400 errors: corrupted transcripts now self-heal where possible, and otherwise a clear error (with a
/rewindhint) ends the loop - Fixed MCP servers configured as
httpthat only speak legacy HTTP+SSE failing to connect when they answer the first request with 422 or another 4xx error - Fixed Streamable HTTP MCP tool calls timing out after about 5 minutes even when a longer per-server
timeoutwas set - Fixed MCP prompts and resources not refreshing when a server sends list-changed notifications without declaring
listChanged - Fixed MCP tool calls refused with 403 insufficient_scope being reported as an expired sign-in: the error now names the missing permissions and points to
/mcpre-authentication - Fixed hook-driven sessions (such as an active
/goal) ending with "Prompt is too long" instead of compacting when the context overflowed again after a reactive compaction - Fixed an active
/goalbeing lost when resuming (--continue/--resume) a session that had compacted - Fixed
claude agentslosing--model,--effort,--permission-mode,--allow-dangerously-skip-permissionsand--agentafter an auto-update relaunch - Fixed a per-turn slowdown when a language server publishes project-wide diagnostics for thousands of files
- Fixed subagents with
model: "opus"on Bedrock, Vertex or Foundry leaving the session's model when its id has no recognizable model family (unlessANTHROPIC_DEFAULT_OPUS_MODELis set) - Fixed self-hosted runner sessions failing every turn with a 401 after a few failed token refreshes, until the next scheduled refresh; the runner now keeps retrying, and fetches a new token after a 401
- Fixed clickable links to local file paths doing nothing in VS Code and other terminals that require a
file://URI - Fixed the transcript renumbering ordered lists in your own messages (typing "3. 2. 1." displayed "3. 4. 5."); numbers and "N)" markers now show as typed
- Fixed AskUserQuestion preview notes being attached to a previously chosen option instead of the highlighted one
- Fixed AskUserQuestion preview mode dropping the highlighted option when submitting a note with Enter
- Fixed a resumed background agent keeping half of an interrupted tool batch when one of its calls was approved with a message
- Fixed a local
claude -p --resumestarted withCLAUDE_CODE_RESUME_INTERRUPTED_TURNnot reporting background tasks the previous process left unfinished - Fixed the first turn of a cloud session sometimes starting without the tools of an SDK-hosted MCP server that was still connecting
- Fixed background agent notifications claiming the agent had no live background work when it was still waiting on its own background task and would resume
- Fixed error hints in Claude Desktop sessions to suggest slash commands like
/usage-creditsinstead of CLI flags that cannot be used there - Fixed
/schedulesaving a routine's prompt without its message role when Claude writes the routine in the shape that listing routines returns - Fixed
/statusnot showing theapiKeyHelperfailure that its own error banner told you to check - Fixed
/fast onin non-interactive sessions reporting on and then turning off under an organization's managed fast mode policy; it now says the organization has disabled it - Fixed the Artifact tool asking you to approve an update to an artifact that it then refused because the session had not read the latest version
- Fixed Cowork and claude.ai cloud sessions with network access on treating reads of a teammate's artifact as if network access were off
- Fixed a plugin or marketplace directory with no git repository of its own taking its version from an enclosing git repository, such as a git-managed
~/.claude - Fixed
--strict-mcp-configwith an empty--mcp-configholding the first non-interactive turn for up toMCP_TIMEOUTon incidental MCP servers - Fixed Stop prompt hooks re-sending their whole prompt on every block in a conversation; repeat blocks now name the condition with a 500-character label
- Fixed extra empty editor windows opening at startup on Linux under Wayland when running inside the Cursor or VS Code terminal
- Fixed an unhandled promise rejection in the Claude apps gateway when Postgres drops a connection during a spend check
- Fixed Claude apps gateway cutting every open stream on SIGTERM: it now lets in-flight requests finish for up to 25 seconds before exiting (
CLAUDE_GATEWAY_DRAIN_TIMEOUT_MS) - Fixed
installed_plugins.jsonbeing rewritten on nearly every start-up when plugin policy comes from remote managed settings, which made Claude Desktop reload every open session's plugins - Fixed headless and SDK sessions making a separate model call for every background task that finished; completions already queued are now answered by one call
- Fixed the Bash tool re-sourcing the shell profile (a multi-second stall on the next command) after every plugin reload; it now does so only when the plugins'
bin/directories changed - Fixed plugins with a top-level
$schemainhooks/hooks.jsonshowing an "unknown key" notice - Fixed MCP connection errors and the MCP login tool's description showing secrets resolved from
${VAR}placeholders in MCP configs - Fixed Bash permission checks for commands that loop over or assign certain special shell variables; these commands now ask for permission
- Fixed worktree-isolated sessions accepting Bash commands with certain nested shell expansions; these are now refused
- Fixed the Edit permission prompt preview sometimes showing a different location than the approved edit in files with multi-byte characters
- Fixed background commands being stopped after 30 idle minutes on machines under mild memory pressure; they're now stopped only when memory is critically low, and the debug log says why
- Fixed a message a subagent sends to the main session disappearing from the Claude Desktop transcript after a relaunch
- Fixed a plugin loaded from a
.zipbeing served from a stale extraction after several overlapping reloads - Fixed a sub-agent's progress summary being replaced by a runaway multi-paragraph reply
- Improved startup in
--input-format stream-jsonsessions: the first turn no longer waits up to 2s for still-connecting MCP servers whose tools tool search defers; they arrive on a later turn - Improved Monitor tool notifications: a script's final output and its exit now arrive as one notification instead of two, saving a model turn
- Improved Artifact tool errors: when you are not signed in to claude.ai the terminal now says so on the first attempt, and Claude is told to stop retrying a rejected call sooner
- Improved artifact publishing: a publish built on an older version is stopped before it is sent, with the newer page to merge
- Improved safety checks before removing an agent worktree that contains submodule checkouts
- Improved
OTEL_LOG_RAW_API_BODIES=file:<dir>output: a newindex.jsonlandrequest_body_id/message.idevent attributes link each response to its request file and transcript message - Improved Claude apps gateway boot: it now tries the first Postgres connection up to three times before exiting, so a database that is reachable a few seconds late no longer fails the boot
- Improved the Claude apps gateway's spend-limit check under load: it now takes one database round trip instead of four, so fewer checks time out on a busy gateway
- Improved Claude apps gateway sign-in rate limit errors:
/loginnow explains the refusal, and the gateway log says which limit was hit and which setting to change - Changed Bedrock, Vertex, Foundry and telemetry-disabled installs to use the v2 MCP client and MCP 2026-07-28 negotiation with direct HTTP servers by default, as other installs already do (opt out:
MCP_SDK_GENERATION=v1orMCP_PROTOCOL_NEGOTIATION=legacy) - Changed
/code-reviewto use leaner inline review prompts for every model that has no tuned settings of its own, instead of spawning many review subagents - Changed
"type": "sdk"MCP entries in.mcp.json, settings, plugins and agent files to be skipped with a warning: only an SDK host application can register in-process servers - Changed artifact watching in local sessions: a new version published elsewhere no longer starts a turn; Claude learns of it from a later Artifact tool result
- Changed plugin and marketplace clones to leave Git LFS files as pointers instead of downloading them;
git lfs pullin the checkout fetches them - Changed self-hosted runners to skip a read-only repository the git host refuses at the access check instead of failing the session start
- Changed the
/statusGitHub line to read "Cloud sessions", and/web-setup,/ultrareview, and teleport messages to say "cloud session" instead of "Claude Code on the web" - [VSCode] Added continuation of the step a window reload interrupted, labeled in the chat, with a Claude Code: Continue After Reload setting to turn it off
- [VSCode] Added Memory and Instructions entries to the Customize menu: Memory shows the auto-memory toggles, the saved memories and the memory folders, and Instructions edits the CLAUDE.md files
- [VSCode] Added a
claudeCode.lockEditorGroupssetting to stop Claude from locking the editor groups it opens in - [VSCode] Fixed a
/btwside question asked in a new conversation's first seconds occasionally showing another session's side-question history - [VSCode] Fixed a brief freeze when the extension first looks up your global gitignore file
- [VSCode] Fixed a message sent while Claude was running a tool disappearing from the conversation after a window reload
- [VSCode] Fixed the Manage Plugins enable toggle and MCP servers dialog rows being unreachable from the keyboard
- [VSCode] Fixed sign-ins and sign-outs made in a terminal not showing until a reload after
CLAUDE_CONFIG_DIRchanged in the Environment Variables setting - [VSCode] Fixed Edit diffs in the chat being cut off at the bottom at some panel widths and for long wrapped lines; diff boxes now fit the rows shown
- [VSCode] Fixed overlapping settings writes from the extension leaving
~/.claude/settings.jsonunparseable or dropping a setting - [VSCode] Fixed Open in New Tab (Ctrl/Cmd+Shift+Esc) sometimes leaving the new tab's message box unfocused, so typing went nowhere until you clicked it
- [VSCode] Fixed reopening a closed Claude tab splitting the editor layout when its locked group still holds another Claude tab and a file
- [VSCode] Fixed New session opening another locked editor group whenever a file tab shared the group with your Claude tab
- [VSCode] Fixed session names shifting sideways in the session picker while typing a search query
- [VSCode] Fixed the plan review card cutting off its Send feedback button and reason field when a plan has several comments; the comment list now scrolls
- [VSCode] Fixed inline code and code blocks in chat replies being unreadable under the High Contrast themes
- [VSCode] Improved screen reader navigation of the conversation: each message is announced as "You" or "Claude", with the tool name for tool steps
- [VSCode] Changed the default global gitignore file to
$XDG_CONFIG_HOME/git/ignorewhenXDG_CONFIG_HOMEis an absolute path - [Claude Code on the web] Added a "Compare against" branch picker to a cloud session's diff view, so you can diff its changes against any branch instead of only the base branch
- [Claude Code on the web] Fixed git operations in cloud sessions failing with "service unavailable" when GitHub's token renewal briefly errors
- [Claude Code on the web] Fixed editing a routine occasionally making it fire twice or re-enabling a routine that had just been paused
- [Claude Code on the web] Fixed commits in cloud sessions occasionally failing with a signing error for a few minutes after the session's credentials refreshed
- [Claude Code on the web] Fixed the toast after saving a routine whose GitHub trigger couldn't be linked to show the reason, such as a per-repository trigger limit, instead of only "edit to retry"
- [Claude Code on the web] Fixed sessions sometimes flipping back to unread right after you mark them read
- [Claude Code on the web] Changed routines to skip a run and retry for up to 72 hours when the owner's GitHub connection is missing, instead of switching the routine off at the first failed check
- [Claude Code on the web] Changed a routine's on-hold notice: when your subscription is paused it now tells you to turn the routine back on yourself instead of promising an automatic resume
- [Claude Tag] Added a Guests setting to the Add channel and Add workspace forms in Claude Tag admin settings, so owners can pick Inherit, Allow, Channel only or Restrict up front
- [Claude Tag] Fixed Claude not answering when another Slack app or bot @mentions it; the tag now gets a reply and wakes Claude in a channel it had stopped following after days of inactivity
- [Claude Tag] Fixed Claude missing another app's message that tagged @claude right after a new Slack channel was created; it's now delivered once Claude has joined
- [Claude Tag] Fixed Claude folding a follow-up sent minutes after its last Slack message into it as a silent edit; late updates such as blockers now post as a new reply that notifies
- [Claude Tag] Fixed Claude's Slack search failing with an error whenever it searched within a single channel; it now returns that channel's matching messages
- [Claude Tag] Fixed a safety-filter stop silently resetting a Slack thread's context when nobody was waiting; Claude now always says so and no longer cancels background work still running
- [Claude Tag] Fixed email addresses in Claude's Slack replies rendering with a visible
mailto:prefix; they now show as the plain, clickable address - [Claude Tag] Fixed Claude refusing to watch an Enterprise Grid channel shared with the whole organization when asked from another workspace in the grid
- [Claude Tag] Fixed the Environment picker in Claude Tag admin settings showing a raw environment ID instead of the environment's name for archived or app-created environments
- [Claude Tag] Improved Claude's live progress checklist in Slack: capped at 2,000 characters, reposted at most every 15 minutes in busy threads, with older "Latest task list" links updated
- [Claude Tag] Removed the repeated guest-attribution note Claude appended to a Slack canvas each time it edited one in a channel using the "Channel only" guest setting
- [Code Review] Fixed re-reviews occasionally leaving a fixed finding's thread open when the new review also filed a lower-severity note under it
- [Code Review] Fixed rare reviews ending with "Code review encountered an error" when GitHub or an internal service failed transiently at launch; they now wait and retry
- [Code Review] Improved how Code Review words each posted finding: short plain sentences that say who is affected, where the code goes wrong, and the fix up front
- [Code Review] Improved the check-run card and PR comment when a review is skipped because of an organization limit: each cause now links the admin page that fixes it
-
π Rust Blog Be alert: targeted attacks on prominent Rustaceans rss
We believe that there is an ongoing campaign targeting rust-lang members and owners of popular crates that is attempting to compromise devices and accounts in order to use them to publish malware.
What we've seen
A video call is set up for something positive β maybe for a job, maybe for a project, maybe for a contract opportunity β and then that's used as a vector to either get the target to install something on their computer (such as a purportedly missing audio codec) or execute another command (for example, via putting a command on the clipboard).
These attackers are setting up new but legitimate seeming company profiles, including plausible LinkedIn presences, in order to pass cursory inspection.
A previous attack of this form targeted many prominent Rust developers in June, and, last month, the
arrayrefcrate was briefly compromised through similar attacks. At this moment we do not know if these are all a part of the same campaign.This attack style is known to be used by the DPRK, and has been seen outside of the Rust community as well.
What you can do
Please take extra care in the near term. Be appropriately suspicious of cold outreaches, and ensure that any calls you have with new people are on platforms you trust β ideally, try to be the one who sets up the call on a platform you already use.
Please also re-check that your accounts look normal: MFA enabled, no unexpected logins on platforms that can track that, and so on.
If you have any concerns about your accounts, please reach out to help@crates.io (for crates.io account concerns) and/or security@rust-lang.org (for any other concerns). We're very happy to help.
-
π Console.dev newsletter htmx 4 rss
Description: Enhance HTML.
What we like: Simplifies the approach to adding attributes to HTML tags for dynamic features. Now uses fetch(). Makes it easy to implement features like infinite scroll, form post, search as you type, polling, and streaming responses. Still pretty minimal (11kb) and no dependencies.
What we dislike: Lots of attributes littered all over your HTML, but that is the point.
-
π Console.dev newsletter Solo rss
Description: Loader for Linux static binaries.
What we like: Makes static binaries for GPU-accelerated code actually work. Makes it easy to build self-contained applications that can benefit from acceleration. Compile to musl, but still use common shared packages.
What we dislike: Incomplete ABI coverage: unsupported glibc calls currently abort. Musl has its own compatibility issues.
-
π seanmonstar Micro: Reading LLM text makes us worse writers rss
The top advice given to anyone wanting to get better at writing, besides just writing, is to read more. Especially good writing. Because we imitate that which we experience more of.
So then, perhaps obviously but it took way too long for me to realize, reading LLM output influences how we write. And since writing is thinking, it seeps in, ablating the voice in my head. Iβm, as one says, horrified.
I value LLMs for their ability to understand hyper-specific search queries. But I want to consider how much of the generated text I read; itβs better to read the human source. Or other non-forced exposure.
-
π Ampcode News One Runner Is Now Enough rss
A runner can now serve many directories, not just the one it was started in. You can point it at specific projects and directories or let it find your Git repositories.

Start a runner and tell it which directories to serve with
--dir. Repeat the flag for each one:$ amp --no-tui --runner-id mac-mini --dir ~/code/amp --dir ~/code/sandcastleOr start it in the directory that holds your checkouts and let it find them:
$ cd ~/code $ amp --no-tui --runner-id mac-mini --discover-dirs--discover-dirsserves every Git checkout up to two levels beneath the current directory and picks up new ones as you clone them.Add or remove directories while the runner is running, without restarting it:
$ amp runner dirs add ~/code/new-repo $ amp runner dirs list $ amp runner dirs remove ~/code/dotfilesThe runner remembers the directories you add this way and serves them again the next time you start it from the same directory.
Oh, They Can Update Themselves Too
Runners now update themselves too. If you leave an
amp --no-tuirunner running, it keeps checking for new releases about once an hour and installs them. Once no thread is running on it, it restarts into the new version, at most once every 12 hours. It keeps its runner ID, its directories, and the rest of its flags.Turn it off with
amp.runner.autoUpdate.enabled: falsein your settings.Read more about serving multiple directories and runner updates in the runner docs.
-
- September 16, 2026
-
π r/LocalLLaMA Qwen 3.8 27B Running for 63 hours on a RTX 3090 to solve the Riemann hypothesis rss
I let Qwen 3.8 27B 4bit quantized with 100K context window run autonomously for 63 hours (50 million+ tokens) to try to solve the RH.
Of course it did not solve it, but the experiment still shows it's internal work, memory organization, strategies used and more.
The interesting thing is that it never hallucinated an answer and never stopped trying new ideas to solve it.
Multiple times it corrected it's own mistakes.
I am really hopeful that one of the unsolved millenium prize problems will be solved by an agent or a swarm of agents powered by an open source model in the next 12 months.
If you want to check out it's internal memories, code, strategies and more I published everything on HF: https://huggingface.co/datasets/gr0010/artificium-riemannhypothesis- experiment
My next goal is to actually use an agent perhaps powered by a smarter open model like GLM 5.3 flash or a swarm of agents, to solve an open math problem.
Please let me know if you tried something similar, what problem you'd suggest to tackle next, and if you have any question.
If you have GPUs consider getting in touch with me, we could run multiple agents to create a swarm and get them to tackle a simple yet open math/coding problem.
submitted by /u/GuiltyBookkeeper4849
[link] [comments] -
π r/LocalLLaMA Xiaomi MiMo 2.6 Live Training Dashboard rss
Cool to see this as it happens!
submitted by /u/skeole
[link] [comments] -
π facebookresearch/faiss v1.15.1 release
See CHANGELOG.md for the full list of changes.
-
π r/LocalLLaMA China's open-weight AI models are now just 4 months behind frontier US offerings, Mozilla report claims β models still lag in some benchmarks but are drastically cheaper to use rss
| submitted by /u/DustNearby2848
[link] [comments]
---|--- -
π HexRaysSA/plugin-repository commits sync repo: +2 releases, -1 release rss
sync repo: +2 releases, -1 release ## New releases - [ida-nexus](https://github.com/hexrayssa/ida-nexus): 0.11.2 - [mcrit-ida](https://github.com/danielplohmann/mcrit-plugin): 1.1.10 ## Changes - [ida-codemode](https://github.com/hexrayssa/ida-codemode): - removed version(s): 0.4.0 -
π r/LocalLLaMA Hey, Meta. Where's those Muse Spark weights? rss
| It was well over a month since Meta promised to release the weights for Muse Spark. Back then (10th August), they were on Spark 1.2. Now we're on 1.3 and still nothing's been released. So it begs the question: will they be releasing the 1.2 weights when 1.4 drops? Or will we get whatever's then-current as open weights? It's ironic given Mark Zuckerberg said at the same time that we can't delay the release of models by "even a month," due to the competition with China. It's been well over a month. He was arguing in the context of new regulations delaying models, but I think it applies equally to the open weights contest as it does to the closed models one. After all, the Chinese models are all open. That's the competition and point of comparison. Have Meta given any sort of explanation for why they're sitting on the weights or how much longer it'll take for them to honour their promise? Will we even get them in light of all the attempts at regulatory capture and dire warnings about how AI is dangerous? submitted by /u/RishiFurfox
[link] [comments]
---|--- -
π New Music Releases Trivium - Dead Inside of Me rss
Trivium - a new release is available:
- 2026-09-16: Dead Inside of Me (Single)
Amazon: Canada | Deutschland | France | United Kingdom | United States
Visit muspy for more information.
-
- September 15, 2026
-
π r/LocalLLaMA Donβt buy a $9K RTX 5090.... instead. rss
- Fly to Taipei. Round-trip from Orlando: $1,081.
- Go to the largest retailer in Taiwan to Spend NT$129,990 β US$4,093.
- Hang out in Taiwan for two weeks. Eat good food. Touch international grass.
- Fly home and flex on r/LocalLLaMA.
https://preview.redd.it/vtve8s6wgrph1.png?width=287&format=png&auto=webp&s=fcc391187f458d2ca023a929e554b880bf425560 https://preview.redd.it/guffjq55hrph1.png?width=340&format=png&auto=webp&s=04cb074f89467c4ad73e36ac6e0570d14d228443 https://preview.redd.it/fe1obue0hrph1.png?width=1095&format=png&auto=webp&s=e3955e613ce4e53d65972b7f6e69e1468b6d6396 submitted by /u/DegenDataGuy
[link] [comments]
---|--- -
π navidrome/navidrome v0.64.0 release
This release brings an experimental Jellyfin Music API , so Jellyfin- compatible music clients like Finamp and Jellify can now connect to Navidrome. Artwork got a new background pipeline with blurred low-quality placeholders and a diagnostic CLI. Under the hood, all IDs move to a uniform canonical 128-bit format , genre and artist filtering is now index-backed, and playlist import on large libraries is dramatically faster. There is also natural sort order, playlist favourites, Refresh Metadata actions, new Catppuccin themes, and many fixes across scanning, transcoding and scrobbling.
β οΈ Breaking Changes / Migration Notes
- All internal IDs are re-encoded to a single canonical 128-bit base62 format. The migration touches every table, so back up your database before upgrading. Clients that cache item IDs (for example, offline downloads) may need to re-sync. (#5824)
- Plugin authors: Extism's built-in HTTP is disabled. Calls through
pdk.NewHTTPRequest(Go),http::request(Rust) or the equivalent in other PDKs now fail withHTTP request ... is not allowed. Plugins must use the host HTTP service instead:host.HTTPSend(Go) ornd_pdk::host::http::send(Rust). Also, plugin HTTP and WebSocket connections to private or loopback addresses are now blocked for named hosts; to reach a LAN service, list its IP or CIDR in the manifest'srequiredHosts, or use a bare"*". (1a8463f7d, 276d767ce) - Shares are always owned by the user who creates them. Admins can no longer create shares on behalf of another user via
userId. (1a8463f7d) - Configuration durations are now validated. Negative values are rejected at startup. (#6002)
- Navidrome now warns about unrecognized options in the config file, so typos no longer fail silently. (#5870)
Security
This release fixes several reported vulnerabilities. We thank the security researchers who responsibly disclosed them.
- Fix SQL injection via the artist
rolesort and filter parameters in the Native API by validating the role against the known list. (4168377b6, GHSA-hm54-32q6-3rcr, reported and fixed by @Sudo-Ivan) - Fix share-ownership spoofing (IDOR) that let a client-supplied
userIdon share creation expose other users' private libraries, and fix a plugin HTTP client SSRF guard bypass via DNS names and redirects by disabling Extism's built-in HTTP and checking the resolved IP at dial time. (1a8463f7d, GHSA-82gh-4ggp-gfg5, reported by @gigioneggiando) - Fix the same SSRF bypass in the plugin WebSocket host service by adding the private-address guard it was missing. (276d767ce, GHSA-pr2j-mfc8-qjcc, reported by @qrn12580)
- Fix login rate limit bypass via spoofed
X-Forwarded-For,X-Real-IPandTrue-Client-IPheaders by keying the limit on the trust-aware client IP. (#6124, GHSA-f295-6wp9-qqfg, reported by @gehan-psbc and @skarn958) - Fix memory exhaustion via a negative
sizeparameter ongetCoverArtand share images, which bypassed the artwork size clamp, by rejecting negative and oversized dimensions before decoding. (#5847, GHSA-f22h-6qxh-rqq2, reported by @arpitjain099) - Enforce track membership on public share streams so a share can only stream the tracks it contains. (#5769 by @deluan)
- Validate every resource ID in a share, load share metadata as the owner, cap login request bodies, create the log file with mode 0600, and stop logging the Last.fm auth token. (#6098 by @deluan)
- Confine plugin filesystem mounts to their root and reject plugin IDs that are unusable as directory names. (#5881, #5886 by @deluan)
- Redact sensitive auth headers from request logs. (82b9a44a1 by @deluan)
Note: Several of the advisories linked above are still in draft on GitHub at the time of writing. Their links will become publicly accessible once the advisories are published. The fixes themselves are already included in this release.
Configuration Changes
Status | Option | Description | Default
---|---|---|---
New |Jellyfin.Enabled| Enable the experimental Jellyfin Music API. (#5730) |false
New |Jellyfin.ServerName| Server name advertised to Jellyfin clients. (#5730) |Navidrome <version>
New |Jellyfin.ExposedPublicUsers| Comma-separated usernames advertised on the unauthenticated public users endpoint. (#5730) |""
New |Jellyfin.MaxConcurrentStreams| Bounds how many Jellyfin collection responses can stream at once. (#5783) |max(2, MaxOpenConns/2)
New |EnableNaturalSorting| Sort names and titles naturally (e.g. "Track 2" before "Track 10"). (#6015) |false
New |MaxImageSize| Cap on the size of artwork images Navidrome will decode. (#5931) |20MB
New |EnableScheduledDBAnalyze| Periodically run a fullANALYZEto keep query planner statistics fresh. (#5740) |trueFor a complete list of all configuration options, see the Configuration Options documentation.
Jellyfin API (Experimental)
- Add an experimental Jellyfin Music API, enabling Jellyfin-compatible music clients to connect to Navidrome. Enable it with
Jellyfin.Enabled = true. (#5730 by @deluan) - Supports library browsing, search, favorites and ratings, playlists, lyrics, Instant Mix (album, playlist and genre sources), ReplayGain normalization, and filtering by year and record label. (#5791, #5948, #5815, #5817 by @deluan, #5809 by @kgarner7)
- Jellyfin clients get sonic similarity features (similar tracks, sonic path) when a sonic similarity plugin is installed, backed by the same engine already exposed over the Subsonic API. (#5782 by @deluan)
- Jellyfin tokens never expire, are scoped to the Jellyfin API, and are revoked when the user changes their password. (#6013 by @deluan)
Artwork
- New artwork pipeline: artwork resolves in the background and pages show a blurred Low Quality Image Placeholder until the real image arrives. External providers are rate-limited and guarded by a circuit breaker, and missing artwork is rechecked slowly instead of on every request. (#5847 by @deluan)
- Make the artwork image size cap configurable. (#5931 by @deluan)
- Fix artist folder being promoted to album folder. (#5856 by @kgarner7)
- Fix Deezer picking the wrong artist among same-name matches, and treat an exhausted Deezer quota as a throttle instead of a missing artist. (#5808, #6068 by @deluan)
UI
- Add Refresh Metadata action to album and artist pages and context menus. (#6036, #6078 by @deluan)
- Add playlist favourites: heart button, list filter, and a sidebar favourites-only toggle. (#5805 by @deluan)
- Add Catppuccin Mocha and FrappΓ© themes, and update Macchiato to match the official palette. (#5835 by @cmyksoda)
- Add Artists, Songs, Playlists and Radio to the Default View options. (#5754, #5801 by @deluan)
- Add Share and Download actions to the Artist detail page. (#5944 by @deluan)
- Show translation completion percentage in the language selector. (#5979 by @deluan)
- Remember the "items per page" selection across sessions. (#5819 by @deluan)
- Give visual feedback when downloading from a share. (#5865 by @deluan)
- Fix logins sometimes showing the wrong user. (#5882 by @deluan, #5767 by @apkatsikas)
- Fix each page's scroll position not being restored when navigating back. (#5892 by @deluan)
- Fix playback starting when closing the disc cover lightbox. (#5901 by @deluan)
- Fix playlist not reloading after rating or loving a track. (#6009 by @polybjorn)
- Fix the album grid resizing in Safari when top menus open. (#6125 by @york9675)
- Fix the album grid hover overlay corners in the Nautiline theme. (#6115 by @deluan)
- Fix transcoding Default Bit Rate not accepting 0. (8d77a49b3 by @deluan)
- Fix the Last.fm link not always showing on the artist details page. (b0e1943d8 by @deluan)
Playlists & Smart Playlists
- Add album-level fields for sorting and filtering in smart playlists. (#5899 by @deluan)
- Add per-playlist
refreshDelayfor stable daily or weekly smart playlists. (#5790 by @deluan) - Store playlist stars and ratings per user. (#5749 by @deluan)
- Make playlist import much faster on large libraries. (#6055 by @deluan)
- Fix in-place playlist edits not being detected by the scanner. (#5914 by @junkerderprovinz)
- Fix track edits being allowed on synced playlists via some APIs. (#5984 by @deluan)
- Fix smart playlist song count being lost on re-import. (#5908 by @deluan)
- Fix deleting many tracks from a playlist at once failing. (#5977 by @deluan)
- Fix the
changedtimestamp not being updated when renaming a smart playlist. (#6082 by @deluan)
Scanner
- Add optional natural sort order for names and titles. (#6015 by @deluan)
- Support the
[bg:]tag and skip unknown tags in LRC lyrics files. (#5966 by @deluan) - Fix album tags being sorted alphabetically instead of keeping the order from the files. (#5872 by @deluan)
- Fix file creation time not being read on Linux. (#6046 by @deluan)
Subsonic API
- Implement the OpenSubsonic
topSongsByArtistIdextension. (#5853 by @kgarner7) - Fix
createShareignoringDefaultDownloadableShare. (#6121 by @deluan) - Fix double brackets when appending subtitle or version to titles. (#5832 by @deluan)
Transcoding & Streaming
- Fix sources already in the player's forced format being re-encoded, and make piped FLAC transcodes seekable. (#6105 by @deluan)
- Fix truncated transcoded streams being delivered as complete. (#6035 by @deluan)
- Fix AAC streams being reported as
audio/mp4instead ofaudio/aac. (#5998 by @justadityaraj) - Fix bit depth being reported for lossy transcode targets. (#5768 by @deluan)
Scrobbling
- Add a per-user scrobble filter. (#5964 by @deluan)
- Add a scrobble history Native API. (#5761 by @kgarner7)
- Use exponential backoff for scrobble retries during provider outages, and honor a provider's request to back off. (#5818, #6028 by @deluan)
- Fix out-of-order playback reports being rejected. (#5793 by @deluan)
Plugins
- Add plugin-specific storage. (#5839 by @kgarner7)
- Add scrobble access to the plugin SDK. (#5795 by @kgarner7)
- Surface the valid agent names in logs and the Plugins UI. (#5910 by @deluan)
- Fix plugin agents not being loaded in CLI commands. (#5959 by @deluan)
- Fix public URLs built by plugins pointing at localhost instead of the caller's address. (#6059 by @deluan)
CLI
- Add an
artworkcommand group (explain,refresh,cancel) for diagnosing and re-driving artwork resolution. (#5957 by @deluan) - Add
missing listandmissing fixsubcommands to deal with files that moved. (#5928 by @zerovox) - Add
doctorandsearch rebuildcommands to detect and recover from search index corruption. (#6069 by @deluan) - Fix
restorewiping the database when the backup file does not exist. (#6085 by @Huang-404-Q) - Fix selective scan
--targetrejecting absolute paths. (#5947 by @deluan) - Fix
pls -pwriting playlist output to stderr instead of stdout. (#5996 by @deluan)
Server
- Make genre and artist filtering much faster across all APIs by using indexed join tables. (#5940, #5930 by @deluan)
- Report the app store or hosting platform via
ND_PLATFORMin insights. (#5956 by @deluan) - Send the Navidrome User-Agent in all outgoing requests. (#6020 by @mintsoft)
- Fix
getScanStatusreportingcount=0for scans not started through the API, fix the folder watcher hanging when it cannot start, and fix startup failing whenMusicFoldercontains a single quote. (#6098 by @deluan)
Database
Packaging & Build
- Upgrade to Go 1.27. (#5990 by @deluan)
- Upgrade the Docker base image to Alpine 3.22, and add
curlto the container image. (#6048 by @deluan, #6116 by @miguelallopes) - Bump TagLib to 2.3.2. (#6088 by @deluan)
- Windows MSI: remember install properties across upgrades. (#5333 by @mintsoft)
- Fix a missing hyphen in the OpenRC script that caused crashes on startup. (#5906 by @alinxviso)
- Fix a typo in the
--prometheus.enableddescription. (#5878 by @0mp)
Translations
- Update Chinese (Simplified) translation. (#5779, #5873 by @fxj368)
- Update Italian translation. (#5848 by @McCio)
- Update Japanese translation. (#6080 by @karigane-cha)
- Update German, Greek, Finnish, Galician, Polish, Portuguese (BR), Thai, Ukrainian and Chinese (Traditional) translations from POEditor. (#5833, #6128 by @deluan)
New Contributors
- @McCio made their first contribution in #5848
- @0mp made their first contribution in #5878
- @alinxviso made their first contribution in #5906
- @IgorPolyakov made their first contribution in #5867
- @junkerderprovinz made their first contribution in #5916
- @justadityaraj made their first contribution in #5998
- @polybjorn made their first contribution in #6009
- @karigane-cha made their first contribution in #6080
- @Shxiao101 made their first contribution in #6097
- @cmyksoda made their first contribution in #5835
- @miguelallopes made their first contribution in #6116
- @Huang-404-Q made their first contribution in #6085
- @zerovox made their first contribution in #5928
- @Sudo-Ivan made their first contribution in 4168377b6
Full Changelog :
v0.63.2...v0.64.0Helping out
This release is only possible thanks to the support of some awesome people!
Want to be one of them?
You can sponsor, pay me a Ko- fi, or contribute with code.Where to go next?
-
π Quarkslab's blog Overview of Passive Optical Networks (PONs) Security rss
You're watching a video on your favourite streaming platform. The platform sends video frames over HTTPS (encrypted), encapsulated in an IP packet with your IP address, ultimately forwarded to your fibre router inside an Ethernet frame. What you might not expect is that this Ethernet frame, containing your encrypted video, is actually received by all your neighbours' routers as well.
The technology behind this behaviour is Passive Optical Networks (PON) : the optical signal received by your router is the same signal received by your neighbours, containing data for several nearby subscribers. It is effectively like having access to your neighbours' Ethernet cables from inside your home, but in one direction only.
What can be extracted then depends entirely on what the subscriber is doing. If protocols are encrypted, the ONU only receives unencrypted metadata (source/destination addresses, ports, etc.), which can still reveal internet habits. If protocols are unencrypted, such as unencrypted DNS, unencrypted VoIP traffic, or legacy protocols, the entire payload is exposed.
Several mechanisms can be activated to encrypt and authenticate each part of the signal so that only the intended recipient can decrypt and process it.
βΉοΈ Glossary
There are many acronyms and definitions used in this article. The glossary is available at Annex A: Glossary.
Fibre networks
Internet Service Providers (ISPs) and companies often use Passive Optical Networks (PONs) to connect end-user devices to their infrastructure using optical fibre in the last kilometre (Fibre-to-the-x (FTTx)). If you have fibre internet in France or Europe, your router is probably using this technology, Gigabit-capable PON (GPON) or 10-Gigabit-capable (Symmetric) PON (XG(S)-PON) in particular.
Before examining the security aspects of PONs, we will first review the evolution of the specifications, how PONs work, and how data is structured on the link.
PON specifications
Over the years, several iterations of PON specifications have been published by the ITU-T (International Telecommunication Union Telecommunication Standardization Sector):
PON specifications timeline based on first specification publication dateAll the iterations in the timeline above are currently in use (although XGS- PON might be preferred to XG-PON) and can often coexist. While GPON has been around for more than 20 years, it is still standard for basic internet plans in France.
As for the latest specification, 50-Gigabit-capable PON (50G-PON), released 5 years ago, some ISPs are only now starting to make real-world deployments. Orange, a French multinational ISP, made a small-scale demonstration of 50G-PON in October 2025 which it calls "the future standard for transmission systems in fibre access networks (FTTH)"1.
Newer PON specifications can be grouped by the PON development phase they belong to:
- Next-generation PON 1 (NG-PON1): XG-PON, XGS-PON.
- Next-generation PON 2 (NG-PON2): NG-PON2.
- Higher Speed PON (HSP): 50G-PON.
- Very High Speed PON (VHSP): in development.
We will stop at HSP/50G-PON, as it is the latest PON specification that has been released.
Competing standards from the IEEE exist as well, to cite a few:
- Ethernet PON (EPON): 1 Gbps symmetric.
- Asymmetric 10G-EPON: 10 Gbps downstream, 1 Gbps upstream.
- Symmetric 10G-EPON: 10 Gbps symmetric.
We will focus on the ITU-T standards as they seem to be prevalent in France and Europe.
Passive Optical Network (PON)
ONUs, OLTs and the ODN
PONs are optical fibre networks connecting Optical Line Terminations (OLTs) to Optical Network Units (ONUs) through Optical Distribution Networks (ODNs).
ODNs used to be built around passive optical filters, splitters and combiners; hence the "Passive" Optical Network designation. However, newer specifications have introduced active elements such as Range Extenders, so the passive part depends on how the ODN is deployed.
The ONU is the component of the router interfacing with the PON and it is sometimes a separate device connected to the router. When a single subscriber uses an ONU, it may also be called an Optical Network Termination (ONT).
A simple description of an ONU would be that it is a device extracting Ethernet frames from the optical signal and forwarding them to the router. However, ONUs support other protocols as well (such as VoIP), have Quality-of- Service features (for time-sensitive signals), Layer-2/Layer-3 features (VLANs, IP configuration, TCP/UDP services, etc), configuration of xDSL if the ONU has xDSL ports, configuration of the security features, etc. The ONU Management and Control Interface (OMCI) specification, which defines the protocol used to configure the ONU, is 700 pages long. ONUs are more complex than they seem.
ONUs are connected to an OLT which can be described as a fibre switch/router, through the ODN. The OLT is located on the service provider's side (ISP for instance).

ONU (top) connected to the OLT (bottom) through an optical fibre. The ONU is plugged on one of the passive optical splitter ports, the splitter is integrated with the OLT here.The Optical Distribution Network: multiplexing optical signals
One key aspect of an Optical Distribution Network (ODN) is that the signal is carried over a reduced number of optical fibres up to a splitter where individual fibres will carry the signal to the end user.
To multiplex signals over a single fibre, several techniques are used depending on the specification or implementer's choice: Wavelength Division Multiplexing (WDM) , Time Division Multiplexing (TDM) or combining both using Time and Wavelength Division Multiplexing (TWDM).
WDM uses different light frequencies to carry multiple signals. Due to carefully chosen frequencies, GPON, XG(S)-PON, NG-PON2 and 50G-PON can coexist on the ODN using a coexistence element (see ITU-T G.980519). For NG-PON2 and HSP, WDM is also used to increase the overall bandwidth by creating several channels that each use a different frequency pair. WDM can also designate the separation of transmit/receive frequencies to use on a single fibre, as opposed to using an individual fibre for each direction.
Taking GPON as an example, the downstream signal is carried on a single fibre from the OLT up to a passive splitter. WDM is used: the upstream and downstream signals use separate wavelengths. The signal is then split (copied) between up to 128 users in the last kilometre and carried using individual fibres. Instead of running 128 individual fibres over up to 60km, only the last few metres will require individual fibres, which reduces the cost and complexity. However, this also means that all 128 users on the same ODN will receive the same downstream signal containing all users' data.
Downstream PONAs for the upstream signal, it uses Time Division Multiple Access (TDMA) , a specific type of TDM : each ONU sends bursts on a timing provided by the OLT, which enables all the individual optical signals from the ONUs to be passively aggregated again before reaching the OLT.
Upstream PONFor HSP and NG-PON2, the combination of WDM and TDM to create channels is designated as TWDM.
The impact of PON architecture on security
As the downstream signal is passively split between all the ONUs, they all receive the same downstream signal which contains their data but also their neighbours'. Basically, all downstream communications are broadcast at the link level, which mandates specific security measures.
As for the upstream signal, it is not carried to other users. However, it can still be intercepted on each individual fibre or when aggregated by the combiner en route to the OLT.
In both cases, authentication and encryption are desirable to avoid eavesdropping, tampering, or man-in-the-middle attacks, which brings us to the threat model of PON specifications.
The PON's protocol stack
In the previous sections, we learned how PONs are structured. This section presents the protocols used to configure the PON link and how data is framed. The objective is to present a condensed view of the frame structure; it can be glossed over and used as a reference for the next security-focused part.
Three main configuration channels: Embedded OAM , PLOAM and OMCI
Before going into the frame structures, let us mention three protocols used by GPON, XG(S)-PON, NG-PON2 and 50G-PON:
- Embedded layer Operation, Administration and Maintenance (Embedded OAM): fields embedded in the frame headers for low latency access, for instance, the frame identifier or the upstream bandwidth allocation.
- Physical layer Operation, Administration and Maintenance (PLOAM): used for other information not sent by the above that relates to the link layer, information that is less time-sensitive but used to configure the connection. For instance, sending the serial number to the OLT, the ONU ID, sending the data encryption key, etc.
- ONU Management and Control Interface (OMCI): the protocol used for high-level configuration of the ONU (the channel is actually called ONU Management and Control Channel (OMCC)). The protocol is defined in the ITU-T G.988 ONU management and control interface (OMCI) specification 15. It uses a Management Information Base (MIB) synchronised between the ONU and the OLT, and allows complex mutual authentication, Layer 2 and Layer 3 configuration, ONU debug, etc.
Four layers
GPON, XG(S)-PON, NG-PON2 and 50G-PON all have similar frame structures, sharing a few similar characteristics:
- When TDM is used (which is most of the time), the upstream frame structure is slightly different from the downstream frame structure.
- The frames have four layers: Physical Medium Dependent (PMD) layer, Transmission Convergence (TC) PHY Adaptation Sublayer, TC Framing Sublayer (FS) and TC Service Adaptation Sublayer.
- The lower layer is the PMD layer, which defines how data is encoded on the optical line.
- The layer between the PMD and user functionalities (Service Data Units, SDUs) is the TC layer. It's called GTC for GPON4, XGTC for XG-PON9, XGS-PON TC10 for XGS-PON, TWDM TC for NG-PON214 and ComTC (for Common TC) for 50G-PON (HSP)17. 50G-PON/Higher Speed PON generalises the TC layer from XG-PON onwards.
- The TC service adaptation sublayer contains (X)GEM frames ((10) Gigabit PON Encapsulation Method) which encapsulate the actual data payload (Ethernet frames for instance).
The diagram below represents a downstream frame and its separation into different layers. This representation deliberately shows only a few fields which are relevant to explain how PON works or are security-related. Technically, it only applies to XG(S)-PON, NG-PON2 and 50G-PON, but GPON is similar. Moreover, while the name and overall purpose of a field might be the same between PON versions, the structure can differ.
XG(S)-PON, NG-PON2 and 50G-PON downstream frame structureThe fields shown on the diagram have the following use:
- Superframe counter (SFC) : 51-bit (XG(S)-PON, NG-PON2 and 50G-PON), 30-bit (GPON), wraps around to 0. It is used in the data encryption process for the counter mode of operation.
- PLOAMd : used by the OLT in the PLOAM configuration protocol, for instance to request a new data encryption key.
- BWmap : not directly security-related, but contains the timings on which upstream frames can be sent for each ONU (for TDMA). More precisely, the OLT assigns Allocation IDs (Alloc-IDs) to the ONUs (a default one is always assigned for OMCI). These Alloc-IDs are then associated with Transmission Containers (T-CONs) which represent a group of logical connections which can be assigned a bandwidth. Finally, each downstream frame contains the bandwidth assignment for the Alloc-IDs, which means each Alloc-ID/T-CON will have a dedicated time to send an upstream burst. Note that the TC layer is only concerned with Alloc-IDs, T-CONs are managed through OMCI and another structure could map to Alloc-IDs. T-CONs are then mapped to (X)GEM ports, the smallest connection entity. Grouping (X)GEM ports into T-CON enables managing bandwidth for QoS (Quality-of-Service) purposes, to prioritise real-time signals such as voice audio.
- Encryption key index : only for XG(S)-PON, NG-PON2 and 50G-PON. Indicates if the downstream payload is: unencrypted, encrypted using key 1, encrypted using key 2 (key index relative to the key slot). GPON does not have such a field: the OLT does not select a key slot but sends a Superframe counter value to the ONU through PLOAMd at which the new key (to be sent) will be used.
In GPON, the FS Header and PSBd are actually merged as a single header (named GTC Header or PCBd) with a similar purpose. Another difference is that while the PLOAMd , BWmap and SFC fields are present in all PON versions, the Encryption key index is only present in XG(S)-PON, NG-PON2 and 50G-PON.
The diagram below represents an upstream frame for XG(S)-PON, NG-PON2 and 50G-PON; it differs slightly for GPON, but it is overall very similar:
XG(S)-PON, NG-PON2 and 50G-PON upstream frame structureThe upstream frames are sent in bursts. Each Alloc-ID is given an opportunity to send data according to the BWMap field sent in the downstream frame. Alloc-ID bandwidth allocations that belong to the same ONU and are consecutive (in time and thus in the BWMap) are called an allocation series. They start with an FS Header and end with an FS Trailer.
Threat models of GPON, XG(S)-PON, NG-PON2 and 50G-PON
All the ITU-T PON specifications referenced have a threat model, which has greatly improved from GPON to XG-PON. XGS-PON/NG-PON2/50G-PON share the XG-PON threat model for the most part.
The GPON4 threat model can be summarised as such:
- An attacker or user having reprogrammed an ONU, or having otherwise access to the incoming optical signal, can access all downstream communications including data from all the other OLT users.
- Other threats such as eavesdropping on the upstream link are considered impractical because the attacker would have to tap into the fibre, sometimes in public places and in a noticeable way for the PON.
The XG-PON specification9 as well as XGS- PON9 10, NG- PON214 and 50G-PON17 have gone back on this model, taking upstream threats into account as well:
- An attacker or user having reprogrammed an ONU, or having otherwise access to the incoming optical signal, can access all downstream communications including data from all the other OLT users.
- An attacker or user having reprogrammed an ONU can impersonate another ONU and forge packets.
- An attacker could intercept or generate traffic at any point on the ODN (which sometimes spans 60 km) between the OLT and the ONU, impersonating the OLT or an ONU.
- An attacker or user could use any of the scenarios above to record and replay packets transmitted on the PON, or modify the packets (bitflips for instance).
Overall, the threat model has improved significantly since GPON, considering security issues in both directions (OLT to ONU and ONU to OLT), as well as eavesdropping anywhere between the OLT and ONUs. This translates into improved security features as well.
Additionally, a study group with members from China Telecommunications Corporation, Verizon, Huawei Technologies Co., Ltd. and ZTE Corporation has published recommendations named "Practical aspects of PON security" starting from 2022. A first supplement has been published20, with the objective "to guide the security experts on operators' expectations about the security of their access networks and on the criteria of a valuable security proposal, as well as the reference to the operators on configuring their networks to achieve the best possible security performance.".
The improved threat model in the supplement separates the threats into several categories:
- Eavesdropping: downstream and upstream.
- Theft of service: unauthorised access to the PON.
- Denial of service.
- Theft of data.
- Impersonation.
- Disruption of operations: disruption from a single ODN to a larger scale (entire ISP for instance).
The supplement insists that "regardless of how strong the link-level encryption strength is, no end-to-end data security property can be derived from it". Indeed, PON specifications are only concerned with establishing a secure channel between an ONU and an OLT, at the link level. This channel is not established between an end user and a service provider directly.
Overall, the supplement gives more context to the threat model and makes recommendations on key management and handling of ONU identifier duplication. The XG-PON ITU-T G.987.39, NG- PON2 ITU-T G.989.314 and 50G-PON ITU-T G.9804.217 specifications' latest amendments actually recommend using this supplement for best practices related to key management. As it is recommended by the specifications, it probably must be implemented.
One threat that does not seem to be mentioned in any of the threat models is the exploitation of vulnerabilities in the OMCI Management Entities, which have a large attack surface. The implementation of the OMCI Management Entities functionalities is down to the manufacturer so this might be outside the specification perimeter however.
PON security measures
Authentication and cryptographic schemes
Authentication in ITU-T PONs can be surprisingly complex, as there are multiple identifiers and schemes available. They are sometimes combined, and the authentication methods do not all ensure the same level of security.
We will separate the use of these identifiers into two categories:
- Identification: the OLT requests an identifier, but there is no secure channel bound to this identifier. In GPON, the OLT can request an identifier and then request an encryption key, but the key is not bound to the identifier, which is why only one authentication scheme is considered for GPON (OMCI-based).
- Authentication: the OLT (and the ONU if the authentication is symmetric) uses a cryptographic scheme to authenticate its counterpart. The results of this authentication can be used to establish a secure channel between the two devices. Keep in mind that, as we'll see in the next sections, a successful authentication does not mean the secure channel is activated, only that it can be.
All PON versions start with an identification step: at the very start of its connection to the OLT, the ONU sends its serial number.
Then, for GPON, cryptographic authentication is entirely optional. For XG-PON and later, a Registration ID -based authentication will always be performed after ONU initialis ation, whether Registration_ID is the default null string or a provisioned one. If a Registration_ID is not provisioned, it will not provide meaningful authentication.
After the mandatory identification or authentication steps, the OLT can start a new authentication process at any point, or request other identifiers. For authentication, up to three cryptographic schemes are available depending on the PON version. Some of these schemes allow for mutual authentication (ONU to OLT, but also OLT to ONU), all of them lead to the creation of a Master Session Key (MSK) which can then be used to establish a secure channel.
Authentication decision diagramThe Logical ONU ID (LOID) / LOID password identifiers often present in ONU web interfaces can be a bit confusing. They seem to be both implemented in custom OMCI Management Entities (as is the case for the Management Entity 65530 used by Huawei ONUs) and in the standard "ONU-G" OMCI Management Entity. The O3 Labs website21 lists several vendor-specific OMCI Management Entities.
Note that a combination of these identifiers and schemes can be used at different steps during the configuration of the ONU. For an XGS-PON link the following sequence could be used:
- Identify the ONU through the serial number sent at the start of the link initialisation.
- Request the Registration ID from the ONU, derive an MSK using the corresponding cryptographic scheme and enable encryption.
- Start the OMCI cryptographic scheme and transition to the new MSK.
The (mutual) secure authentication mechanisms
In the previous section, we mentioned three authentication mechanisms based on cryptography: Registration ID-based, OMCI-based and IEEE 802.1X-based.
Only the last two are mutual authentication schemes that authenticate both the ONU and the OLT.
Registration ID-based authentication
Only available in XG(S)-PON, NG-PON2 and 50G-PON. This is the default authentication mode based on a 36-byte value called Registration_ID and it is not mutual. The Registration_ID is requested by the OLT during the ONU activation process and can be queried at any time through a PLOAM message, which is unencrypted.
This mechanism is thus vulnerable to several threats, for instance:
- An attacker can unplug the target optical fibre, plug it in their OLT, request the Registration_ID , derive the keys and use them to decrypt the encrypted data encryption key transmitted through PLOAM after the device has been plugged back to the original OLT.
- An attacker could tap at any point between the targeted user and the OLT and see the Registration_ID in clear form, derive the keys and use them to decrypt the encrypted data encryption key transmitted through PLOAM.
The Registration_ID is not meant to be changed regularly, the attacker can query it once and reuse it at any time. Moreover, if it is unchanged, the default is used.
A key consideration is that Registration_ID \def\pelican{\textrm{pelican}^2} \text{Registration\ID} has a default value (0x00)36 \def\pelican{\textrm{pelican}^2} (0x00){36}, which will be used for the Registration ID-based authentication unless a Registration_ID has been provisioned. Thus, the specifications effectively allow the use of one of the cryptographic authentication schemes with a known (weak) secret. Having the possibility to use an unauthenticated/unencrypted channel, which would not provide a false sense of security, would seem preferable.
Registration ID-based MSK derivation
Let:
- Registration_ID \def\pelican{\textrm{pelican}^2} \text{Registration\_ID} be the 36-byte Registration ID.
- TMSK \def\pelican{\textrm{pelican}^2} T_{MSK} be the required MSK length.
- K \def\pelican{\textrm{pelican}^2} K be the 128-bit AES key used in the AES-ECMAC definition.
- M \def\pelican{\textrm{pelican}^2} M be the input message used in the AES-ECMAC definition.
- Tlen \def\pelican{\textrm{pelican}^2} Tlen be the requested MAC output length in bits.
- MlessLastBlock \def\pelican{\textrm{pelican}^2} M_{\text{lessLastBlock}} be the M \def\pelican{\textrm{pelican}^2} M with its final 16 octets removed.
MSK \def\pelican{\textrm{pelican}^2} MSK is derived the following way:
MSK={AES-128-CMAC&af((0x55)16,Registration_ID,128),TMSK=128AES-128-ECMAC&af((0x55)16,Registration_ID,256),TMSK=256 (50G-PON/HSP) \def\pelican{\textrm{pelican}^2} MSK = \begin{cases} \operatorname{AES-128-CMAC}\left((\text{0x55}){16}, \text{Registration\_ID}, 128\right), & T{MSK}=128 \\[6pt] \operatorname{AES-128\text{-}ECMAC}\left((\text{0x55}){16}, \text{Registration\_ID}, 256\right), & T{MSK}=256 \text{ (50G-PON/HSP)} \end{cases}
where
AES-128-ECMAC&af(K,M,Tlen)={AES-128-CMAC&af(K,M,Tlen),Tlenβ€128AES-128-CMAC&af(K,MlessLastBlock,128)&smidAES-128-CMAC&af(K,M,128),Tlen=256 \def\pelican{\textrm{pelican}^2} \operatorname{AES-128\text{-}ECMAC}(K, M, Tlen) = \begin{cases} \operatorname{AES-128-CMAC}(K, M, Tlen), & Tlen \leq 128 \\[4pt] \operatorname{AES-128-CMAC}\left(K, M_{\text{lessLastBlock}}, 128\right) | \operatorname{AES-128-CMAC}(K, M, 128), & Tlen = 256 \end{cases}
OMCI-based authentication
This is one of the two mutual secure authentication mechanisms, now defined in ITU-T G.98815 (originated in ITU-T G.984.45 for GPON). The scheme assumes a Pre-Shared Key (PSK \def\pelican{\textrm{pelican}^2} PSK) has been provisioned on both the ONU and OLT beforehand.
A three-step challenge-based mutual authentication is used:
Three-step OMCI authentication
- The OLT sends its list of supported MAC (Message Authentication Code) functions and OLT random challenge \def\pelican{\textrm{pelican}^2} OLT\ random\ challenge to the ONU.
- Then, the ONU selects one of the supported OLT MAC functions, then sends the ONU random challenge \def\pelican{\textrm{pelican}^2} ONU\ random\ challenge and the following MAC to the OLT: MACFunction(PSK,(selected_cryptographic_capabilities&smidOLT random challenge&smidONU random challenge&smid(0x00)16)) \def\pelican{\textrm{pelican}^2} \text{MACFunction}(\text{PSK}, (selected\cryptographic\_capabilities|OLT\ random\ challenge|ONU\ random\ challenge|(0x00){16}))
- Finally, OLT then sends a MAC to the ONU as well: MACFunction(PSK,(selected_cryptographic_capabilities&smidONU random challenge&smidOLT random challenge&smidONU Serial Number)) \def\pelican{\textrm{pelican}^2} \text{MACFunction}(\text{PSK}, (selected\_cryptographic\_capabilities|ONU\ random\ challenge|OLT\ random\ challenge|ONU\ Serial\ Number))
The OLT advertises its supported MACFunction \def\pelican{\textrm{pelican}^2} MACFunction in the "OLT crypto capabilities" attribute of the OMCI "Enhanced security control" Management Entity. Then, the ONU chooses one of these MACFunctions \def\pelican{\textrm{pelican}^2} MACFunctions and sets the "ONU selected crypto capabilities" attribute of the OMCI "Enhanced security control" Management Entity. It is then used as onu_selected_cryptographic_capabilities \def\pelican{\textrm{pelican}^2} \text{onu\_selected\_cryptographic\_capabilities}.
MACFunction \def\pelican{\textrm{pelican}^2} MACFunction is chosen from the following list:
- AES-CMAC-128 (default, must be supported).
- HMAC-SHA-256.
- HMAC-SHA-512.
Master Session Key derivation
Finally, the MSK \def\pelican{\textrm{pelican}^2} MSK is derived from the PSK \def\pelican{\textrm{pelican}^2} PSK and the challenges. The following formula is used when a 128-bit MSK \def\pelican{\textrm{pelican}^2} MSK is required, which is always the case for GPON, XG(S)-PON and NG-PON2:
OMCI-based 128-bit MSK \def\pelican{\textrm{pelican}^2} MSK derivation
MSK=MACFunction(PSK,(OLT random challenge&smidONU random challenge)), take the 128 most significant bits. \def\pelican{\textrm{pelican}^2} \text{MSK} = \text{MACFunction}(\text{PSK}, (OLT\ random\ challenge | ONU\ random\ challenge))\text{, take the 128 most significant bits.}
However, 50G-PON also supports 256-bit MSKs. When combining the ITU-T G.988 (OMCI)15 and ITU-T G.9804.2 (50G-PON)17 specifications, it is unclear how MSK \def\pelican{\textrm{pelican}^2} MSK should be derived in this situation. ITU-T G.9804.2 also defers to ITU-T G.987.39 for OMCI authentication.
When MACFunction=AES-CMAC-128 \def\pelican{\textrm{pelican}^2} \text{MACFunction}=\text{AES-CMAC-128}, the equation is clear:
OMCI-based 50G-PON 256-bit MSK derivation for MACFunction=AES-CMAC-128 \def\pelican{\textrm{pelican}^2} \text{MACFunction}=\text{AES-CMAC-128}
MSK=AES-128-ECMAC&af(PSK,(OLT random challenge&smidONU random challenge),256) \def\pelican{\textrm{pelican}^2} \text{MSK} = \operatorname{AES-128\text{-}ECMAC}\left(\text{PSK}, (OLT\ random\ challenge | ONU\ random\ challenge), 256\right)
where
AES-128-ECMAC&af(K,M,Tlen)={AES-128-CMAC&af(K,M,Tlen),Tlenβ€128AES-128-CMAC&af(K,MlessLastBlock,128)&smidAES-128-CMAC&af(K,M,128),Tlen=256 \def\pelican{\textrm{pelican}^2} \operatorname{AES-128\text{-}ECMAC}(K, M, Tlen) = \begin{cases} \operatorname{AES-128-CMAC}(K, M, Tlen), & Tlen \leq 128 \\[4pt] \operatorname{AES-128-CMAC}\left(K, M_{\text{lessLastBlock}}, 128\right) | \operatorname{AES-128-CMAC}(K, M, 128), & Tlen = 256 \end{cases}When MACFunction=HMAC-SHA-256 \def\pelican{\textrm{pelican}^2} \text{MACFunction}=\text{HMAC-SHA-256} or MACFunction=HMAC-SHA-512 \def\pelican{\textrm{pelican}^2} \text{MACFunction}=\text{HMAC-SHA-512} are used, the specifications imply one of two things:
- Following ITU-T G.9804.2 Annex C "Secure mutual authentication", the output of MACFunction \def\pelican{\textrm{pelican}^2} \text{MACFunction} is truncated to 256 bits, as HMAC-SHA-256 \def\pelican{\textrm{pelican}^2} \text{HMAC-SHA-256} generates a 256-bit value and HMAC-SHA-512 \def\pelican{\textrm{pelican}^2} \text{HMAC-SHA-512} a 512-bit value.
- ITU-T G.988 requires MSK \def\pelican{\textrm{pelican}^2} MSK to be truncated to 128 bits. According to ITU-T G.9804.2 clause 9.13, MSK \def\pelican{\textrm{pelican}^2} MSK must be extended to 256 bits using the same process as the "OMCI-based 50G-PON 256-bit MSK derivation for MACFunction=AES-CMAC-128 \def\pelican{\textrm{pelican}^2} \text{MACFunction}=\text{AES-CMAC-128}" equation above.
The key contradictory quotes are available in Annex C: Contradictory specification quotes relative to the derivation of a 256-bit MSK \def\pelican{\textrm{pelican}^2} MSK for HMACs with an output size of 256-bit or more.
As both the ONU and OLT must derive the same MSK \def\pelican{\textrm{pelican}^2} MSK, a manufacturer testing this specific case with different ONUs or OLTs would notice any implementation mismatch. A clarification of the specification would make clear what is actually implemented, but all manufacturers should have the same implementation eventually. As 50G-PON is not widely deployed, they might not have faced this choice yet, especially with these specific MACFunctions \def\pelican{\textrm{pelican}^2} \text{MACFunctions}.
IEEE 802.1X-based authentication
This is the second mutual secure authentication mechanism, only available in XG(S)-PON, NG-PON2 and 50G-PON. Its implementation is mostly detailed in Annex D of ITU-T G.987.39.
IEEE 802.1X supports many authentication methods through the Extensible Authentication Protocol (EAP)23. EAP- GPSK24 which is based around a pre-shared key, must be supported according to ITU-T G.987.39. EAP- TLS25 is also mentioned in the specification and allows the use of public-key cryptography. Any EAP method that supports mutual authentication and the generation of a secret MSKEAP \def\pelican{\textrm{pelican}^2} MSK_{EAP} can be used.
RFC 374823 mentions that the MSKEAP \def\pelican{\textrm{pelican}^2} MSK_{EAP} generated must be at least 64 bytes long, however we need only 16 bytes or 32 bytes (50G-PON only).
IEEE 802.1X-based MSK derivation
Let TMSK \def\pelican{\textrm{pelican}^2} T_{MSK} be the required MSKPON \def\pelican{\textrm{pelican}^2} MSK_{PON} size in bits. MSKPON \def\pelican{\textrm{pelican}^2} MSK_{PON} is derived from MSKEAP \def\pelican{\textrm{pelican}^2} MSK_{EAP} as follows:
MSKPON=TMSK most significant bits of MSKEAP \def\pelican{\textrm{pelican}^2} MSK_{PON} = T_{MSK}\text{ most significant bits of } MSK_{EAP}
A note on Forward Secrecy
Only one authentication scheme, the IEEE 802.1X-based scheme with the right EAP (EAP-TLS with a Diffie-Hellman key exchange for instance), might lead to an encrypted session that provides perfect forward secrecy. For the other schemes, the leak of the Registration_ID or PSK would enable attackers to decrypt the signal in harvest now, decrypt later attacks. The encrypted data encryption key contained in the PLOAM messages could be decrypted, and then the payloads of the XGEM frames.
Key Derivation
MSK \def\pelican{\textrm{pelican}^2} MSK and its derived keys have three purposes: encrypting the data encryption key (using the MSK \def\pelican{\textrm{pelican}^2} MSK for GPON or the Key Encryption Key (KEK \def\pelican{\textrm{pelican}^2} KEK) otherwise), authenticating PLOAM messages and authenticating OMCI messages (XG-PON and above only).
Key derivation decision diagramNote that the typos and wordplays in the strings match the actual values used by the specifications, as specific string lengths were required.
XG(S)-PON and NG-PON2 derivations
SK=AES-128-CMAC(MSK,(SN&smidPON-TAG&smid"SessionK")) \def\pelican{\textrm{pelican}^2} SK = \text{AES-128-CMAC}(MSK, (\text{SN}|\text{PON-TAG}|\text{"SessionK"})) OMCI_IK=AES-128-CMAC(SK,"OMCIIntegrityKey") \def\pelican{\textrm{pelican}^2} OMCI\_IK = \text{AES-128-CMAC}(SK, \text{"OMCIIntegrityKey"}) PLOAM_IK=AES-128-CMAC(SK,"PLOAMIntegrtyKey") \def\pelican{\textrm{pelican}^2} PLOAM\_IK = \text{AES-128-CMAC}(SK, \text{"PLOAMIntegrtyKey"}) KEK=AES-128-CMAC(SK,"KeyEncryptionKey") \def\pelican{\textrm{pelican}^2} KEK = \text{AES-128-CMAC}(SK, \text{"KeyEncryptionKey"})
50G-PON derivations
Let:
- K \def\pelican{\textrm{pelican}^2} K be the key used in the BC-ECMAC definition.
- M \def\pelican{\textrm{pelican}^2} M be the input message used in the BC-ECMAC definition.
- Tlen \def\pelican{\textrm{pelican}^2} Tlen be the requested MAC output length in bits.
- BC \def\pelican{\textrm{pelican}^2} BC be the chosen Block Cipher.
- MlessLastBlock \def\pelican{\textrm{pelican}^2} M_{\text{lessLastBlock}} be M \def\pelican{\textrm{pelican}^2} M with its final 16 octets removed.
SK=BC-ECMAC(MSK,(SN&smidPON-TAG&smidPON-TAG&smidSN),Tlen) \def\pelican{\textrm{pelican}^2} SK = \text{BC-ECMAC}(MSK, (SN|\text{PON-TAG}|\text{PON-TAG}|SN), Tlen) OMCI_IK=BC-ECMAC(SK, "OMCIIntegrityKeyMakeOMCImoreSafe",Tlen) \def\pelican{\textrm{pelican}^2} OMCI\IK = \text{BC-ECMAC}(SK, \text{ "OMCIIntegrityKeyMakeOMCImoreSafe"}, Tlen) PLOAM_IK=AES-128-CMAC(SK16 least significant bytes,"PLOAMIntegrtyKey") \def\pelican{\textrm{pelican}^2} PLOAM\_IK = \text{AES-128-CMAC}(SK\text{16 least significant bytes}, \text{"PLOAMIntegrtyKey"}) KEK=BC-ECMAC(SK,"KeyEncryptionKeyMakeKEKMoreSafey",Tlen) \def\pelican{\textrm{pelican}^2} KEK = \text{BC-ECMAC}(SK, \text{"KeyEncryptionKeyMakeKEKMoreSafey"}, Tlen) where BC-ECMAC&af(K,M,Tlen)={BC-CMAC&af(K,M,Tlen),Tlenβ€128BC-CMAC&af(K,MlessLastBlock,128)&smidBC-CMAC&af(K,M,128),Tlen=256 \def\pelican{\textrm{pelican}^2} \operatorname{BC\text{-}ECMAC}(K, M, Tlen) = \begin{cases} \operatorname{BC-CMAC}(K, M, Tlen), & Tlen \leq 128 \\[4pt] \operatorname{BC-CMAC}\left(K, M_{\text{lessLastBlock}}, 128\right) | \operatorname{BC-CMAC}(K, M, 128), & Tlen = 256 \end{cases}
For GPON, the data encryption key is only sent encrypted when the OMCI authentication is used; otherwise it is sent in clear form. The key is always sent encrypted in XG(S)-PON, NG-PON2 and 50G-PON, using the KEK \def\pelican{\textrm{pelican}^2} KEK key derived from the MSK.
The other two keys derived from the MSK in XG(S)-PON, NG-PON2 and 50G-PON are used for the authentication of OMCI and PLOAM messages, so only OMCI and PLOAM have authenticity checks, not the main payload. GPON does not have such a mechanism.
Authentication of PLOAM and OMCI messages
Only XG(S)-PON, NG-PON2 and 50G-PON authenticate the PLOAM and OMCI messages; GPON does not. Authentication ensures the messages have been sent by the right peer and that they have not been tampered with.
The PLOAM and OMCI Message Integrity Check (MIC) values are derived the following way:
PLOAM and OMCI MIC calculation
PLOAM-MIC=AES-128-CMAC(PLOAM_IK,(Cdir&smidPLOAM_CONTENT),64) \def\pelican{\textrm{pelican}^2} \text{PLOAM-MIC} = \text{AES-128-CMAC} (\text{PLOAM\IK}, (C{dir} | \text{PLOAM\_CONTENT}), 64)
OMCI-MIC=BC-CMAC(OMCI_IK,(Cdir&smidOMCI_CONTENT),32) \def\pelican{\textrm{pelican}^2} \text{OMCI-MIC} = \text{BC-CMAC} (\text{OMCI\IK}, (C{dir} | \text{OMCI\CONTENT}), 32)
where Cdir=0x01 \def\pelican{\textrm{pelican}^2} C{dir} = 0x01 for downstream and Cdir=0x02 \def\pelican{\textrm{pelican}^2} C_{dir} = 0x02 for upstream.and
BC-CMAC \def\pelican{\textrm{pelican}^2} \text{BC-CMAC} is AES-128-CMAC \def\pelican{\textrm{pelican}^2} \text{AES-128-CMAC} for XG(S)-PON and NG- PON2. For 50G-PON, the chosen block cipher used across data encryption, key derivation and message integrity checks is used for OMCI. This allows 50G-PON to use stronger keys (256-bit). PLOAM, however, always uses AES-128-CMAC \def\pelican{\textrm{pelican}^2} \text{AES-128-CMAC}.
PLOAM and OMCI authentication is always enabled; however, before any MSK has been derived a default key is used for PLOAM: 0x5516 \def\pelican{\textrm{pelican}^2} 0x55_{16}. The default key is always used for downstream broadcast PLOAM messages, as well as some unicast PLOAM messages such as the Serial_Number_ONU , Deactivate_ONU-ID , Request_Registration and Registration PLOAM messages. After that, the keys derived from the MSK established from the Registration_ID are used, and finally the keys derived from any new MSK established from one of the authentication mechanisms.
Generating the data encryption keys
There are two types of data encryption keys: unicast and multicast (broadcast). In the previous sections, we only mentioned which keys are used to encrypt the unicast data encryption key; not how it is generated.
The unicast data encryption key used in the GPON, XG(S)-PON and NG-PON2 specifications is generated by each ONU, not the OLT.
GPON, XG-PON and NG-PON2 data encryption key generation
EncryptionKey=ONU-generated random generated value of size 128 bits \def\pelican{\textrm{pelican}^2} EncryptionKey = \text{ONU-generated random generated value of size 128 bits}
A secure random number generator must be used.
Moreover, if the key is not generated properly, all the authentication and key encryption will not matter as the attacker could bruteforce the data encryption key. Thus, according to the XG(S)-PON and NG-PON2 specifications, "the ONU generates a new encryption key using a random number generator suitable for cryptographic purposes"14. The GPON specification has a similar mention "The ONU should generate a cryptographically unpredictable key."4.
As for 50G-PON, the unicast data encryption key is now derived from both an OLT and an ONU random number, instead of being taken directly from the random number generator output:
50G-PON data encryption key generation
Let:
- KEK \def\pelican{\textrm{pelican}^2} \text{KEK} be the Key Encryption Key derived from MSK \def\pelican{\textrm{pelican}^2} MSK.
- BC \def\pelican{\textrm{pelican}^2} \text{BC} be the chosen Block Cipher.
- Tlen \def\pelican{\textrm{pelican}^2} \text{Tlen} be the BC \def\pelican{\textrm{pelican}^2} \text{BC} key size.
- KeyControl_RandomX \def\pelican{\textrm{pelican}^2} \text{KeyControl\_RandomX} and KeyControl_RandomX \def\pelican{\textrm{pelican}^2} \text{KeyControl\_RandomX} be values sent to the ONU through PLOAM by the OLT.
- BC-ECMAC \def\pelican{\textrm{pelican}^2} \text{BC-ECMAC} as previously defined.
- BC-ECB \def\pelican{\textrm{pelican}^2} \text{BC-ECB} be BC \def\pelican{\textrm{pelican}^2} \text{BC} with the ECB cipher mode.
EncryptionKey=BC-ECMAC(KEK,ONUKeyContrib&smidOLTKeyContrib,Tlen) \def\pelican{\textrm{pelican}^2} EncryptionKey = \text{BC-ECMAC}(KEK, \text{ONUKeyContrib}|\text{OLTKeyContrib}, Tlen)
where
OLTKeyContrib={BC-ECB&af(KEK,KeyControl_RandomX),Tlen=128BC- ECB&af(KEK,KeyControl_RandomX|KeyControl_RandomY),Tlen=256 \def\pelican{\textrm{pelican}^2} \text{OLTKeyContrib} = \begin{cases} \operatorname{BC-ECB}(KEK, \text{KeyControl\_RandomX}), & Tlen=128 \\[4pt] \operatorname{BC-ECB}(KEK, \text{KeyControl\_RandomX|KeyControl\_RandomY}), & Tlen=256 \end{cases}
and
ONUKeyContrib=ONU-generated random generated value of size Tlen \def\pelican{\textrm{pelican}^2} \text{ONUKeyContrib} = \text{ONU-generated random generated value of size Tlen}
A secure random number generator must be used.However, the key is still generated on the ONU side, sent encrypted to the OLT and used as-is. Thus, it seems that the ONU can still hardcode a key or ignore the OLT's contribution, and is responsible for the key strength more generally. But the ONU can now use the OLT entropy pool to increase the data encryption key strength.
Finally, for XG-PON and above, the data encryption key is sent encrypted to the OLT, using the chosen block cipher in ECB mode and KEK \def\pelican{\textrm{pelican}^2} KEK as key. For GPON, MSK \def\pelican{\textrm{pelican}^2} MSK is used instead of KEK \def\pelican{\textrm{pelican}^2} KEK, and encryption of the data encryption key not mandatory.
Encryption of the data encryption key
For GPON Encrypted EncryptionKey=AES-128-ECB&af(MSK,Encryption Key), \def\pelican{\textrm{pelican}^2} \text{Encrypted EncryptionKey} = \operatorname{AES-128-ECB}(MSK, \text{Encryption Key}),
For XG-PON and above Encrypted EncryptionKey=BC-ECB&af(KEK,Encryption Key), \def\pelican{\textrm{pelican}^2} \text{Encrypted EncryptionKey} = \operatorname{BC-ECB}(KEK, \text{Encryption Key}),
where BC=AESβ128 \def\pelican{\textrm{pelican}^2} BC = AES-128 for XG(S)-PON and NG-PON2.XG(S)-PON, NG-PON2 and 50G-PON also allow the use of a multicast data encryption key which is generated on the OLT and allows a frame to be encrypted once so that it can be decrypted by multiple ONUs.
Enabling encryption
Encryption is mostly disabled by default for all PON versions.
For GPON, the encryption of a GEM port is activated through PLOAM, and only the downstream frames are encrypted. For XG-PON and above, the default XGEM port which is used for OMCI is always set for bidirectional unicast encryption, other XGEM ports must be provisioned (unicast/multicast, direction of the encryption, etc). However, the encryption of the frame is still enabled by the Key_index field in the frame header, although the XG-PON specification does mention that it must be done "within the explicitly configured or pre-defined capabilities of the associated XGEM port".
Enabling encryption decision diagramFor the encryption of the OMCI messages (on the OMCC channel), no OMCI Management Entity needs to be configured. For XG-PON and above, ITU-T G.98815 mentions that "If the GEM frame itself contains an encryption key index, it is understood to refer to the unicast key and to require encryption both up- and downstream." and the XG(S)-PON and above specifications say "Whenever the default XGEM port traffic is encrypted in the downstream direction, the ONU is expected to encrypt the default XGEM port traffic upstream". One interpretation of that last quote could imply that an unencrypted frame can be sent to the default (OMCI) XGEM port, which slightly contradicts the ITU-T G.988 specification.
Implementers should make sure that the Key_index value of a specific frame matches the configuration of the XGEM port.
PLOAM messages and OMCI Management Entities relevant to security features
There are a few PLOAM messages and OMCI Management Entities related to security features that are scattered in the specifications. Annex B: PLOAM and OMCI security-related messages can be used as a reference and might be useful for the next section.
Encrypted communications
Finally! We've identified the ONU, passed the authentication process, established an MSK , derived the keys, generated a random data encryption key and sent it encrypted to the OLT, we've enabled the encryption on the (X)GEM port, set the right fields in the (X)GEM header, authenticated the OMCI and PLOAM messages (unless GPON), and at last we can send our encrypted message!
Block cipher and CTR mode
First of all, only the payload of the X(GEM) frame is encrypted, not the X(GEM) header.
The default encryption method is AES-128-CTR (AES-128 with the counter mode of operation specified in NIST SP 800-38A22) and it must be supported by both the ONU and the OLT. In addition to AES-128, 50G-PON (ITU-T G.9804.217) must also support AES-256. However, for 50G-PON, the OMCI "ONU2-G" Management Entity can advertise and enable support for other block ciphers: Camellia-128, Camellia-256 and SM4-128.
While technically, the NIST SP 800-38A22 "assumes that a FIPS-approved symmetric key block cipher algorithm has been chosen as the underlying algorithm", and Camellia and SM4 are not NIST- approved, the same counter mode is used for all block ciphers.
Even though CTR is a strong encryption mode, it does not provide authentication, which means an attacker can blindly modify the encrypted payload. Other protocols such as TLS 1.3 use AEAD (Authenticated encryption with additional data) modes to provide both encryption and authentication of the main payload, as well as authentication of additional data that must stay visible (a header for instance).
The Counter
The counter is reset at the start of each (X)GEM frame, and its initial value is called Initial Counter Block in XG-PON and later but this designation works for GPON as well. It is then increased by one after each 16-byte block inside the (X)GEM frame.
The Initial Counter Block is a function of the SFC which is sent by the OLT and the Intraframe counter (IFC). The IFC is reset to 0 at the start of each FS frame, increased every 4 bytes for GPON and every 16 bytes for XG-PON and later. The IFC value used in the Initial Counter Block calculation is the IFC value at the first byte of the GEM header for GPON, and at the position of the first four bytes for XG-PON and later (XGEM frames are aligned on a 4-byte boundary).
The figures below represent the SFC , IFC and how (X)GEM frames are encrypted for downstream GPON and XG-PON (and above).
Encryption of a downstream (GPON) GEM frame
Encryption of a downstream XGEM frameDuplicated counter blocks
The XG-PON specification and above mention two SFC values which lead to duplicated counter blocks in both directions:
- For XG(S)-PON and NG-PON2: SFC(49..0)=0b1(0)49 \def\pelican{\textrm{pelican}^2} SFC(49..0)=0b1(0){49} and SFC(49..0)=0b0(1)49 \def\pelican{\textrm{pelican}^2} SFC(49..0)=0b0(1){49}. According to the specifications, the duplicated counter blocks appear for 250ΞΌs once every 4000 years. SFC(49..0) \def\pelican{\textrm{pelican}^2} SFC(49..0) is used, as one of the 51 bits of SFC is dropped before the counter calculation.
- For HSP/50G-PON: SFC(47..0)=0b1(0)47 \def\pelican{\textrm{pelican}^2} SFC(47..0)=0b1(0){47} and SFC(47..0)=0b0(1)47 \def\pelican{\textrm{pelican}^2} SFC(47..0)=0b0(1){47}. According to the specification, the duplicated counter blocks appear for 100ΞΌs once every 1000 years. SFC(47..0) \def\pelican{\textrm{pelican}^2} SFC(47..0) is used, as three of the 51 bits of SFC are dropped before the counter calculation.
where SFC(x..y) \def\pelican{\textrm{pelican}^2} SFC(x..y) represents SFC \def\pelican{\textrm{pelican}^2} SFC's bits x to y (included) in that order.
To mitigate this issue, the specifications recommend initialising SFC to a small value.
As for the upstream payloads, GPON does not encrypt them. For XG-PON and above, upstream frames can be encrypted, when they are the operation is very similar to the encryption of downstream frames.
The main difference is how IFC is calculated: instead of starting at 0 \def\pelican{\textrm{pelican}^2} 0, IFC starts with a value derived from the StartTime at which the upstream burst is sent. This way, IFC is unique for each Alloc-ID.
Reduced data encryption strength: why?
All the ITU-T PON specifications discussed specify the use of data encryption keys with "reduced effective length".
Instead of generating a 128-bit encryption key, an ONU may generate a key of size Leff \def\pelican{\textrm{pelican}^2} L_{eff} bits where Leff \def\pelican{\textrm{pelican}^2} L_{eff} is a multiple of 8, filling the remaining most significant bytes with 0x55 \def\pelican{\textrm{pelican}^2} 0x55.
Leff \def\pelican{\textrm{pelican}^2} L_{eff} can be reported through the OMCI "Enhanced security control" Management Entity and the "Effective key length" attribute, but it is optional.
While this provision was probably in place to support older devices, it is odd that it is still present in newer specifications that require more capable devices.
Bringing it all together: ONU initialisation and key switching
While we have all the bricks to authenticate and encrypt secure channels between ONUs and OLTs, timing is important: some authentication methods are not available right away, keys are renewed regularly (key switching) or must transition from one authentication method to another, etc.
The diagram below presents the key events of an XG-PON ONU from power-up to the establishment of a secure data channel, highlighting the transitions between authentication schemes. Note that this is a "happy path" scenario; it is designed to demonstrate the integration of the security mechanisms discussed in this post rather than provide an exhaustive state-machine analysis of the full specification.
On the left of the diagram are represented the approximate ONU and key management states that are used in state-machines in the specification; not all events are displayed and some are simplified.
XG-PON timeline for power-up to secure channelThe data encryption key should be regularly regenerated by the ONU on the OLT's request; however, the renewal frequency is at the OLT's discretion.
During key renewal, all PON specifications implement measures to ensure only valid keys are used and the link is not left broken. For GPON, the OLT simply sends a superframe counter value to the ONU, at which the new key will be used. For XG-PON and above, the process is more complex and involves timers and state machines. While the XG-PON and later specifications mention two ONU timers (the "ONU key exchange waiting timer" and "Key Ack waiting timer"), the ITU-T Supplement 8120 deprecates them "the ONT-side timers are deprecated", leaving timeout management to the OLT.
Conclusion
ITU-T PON specifications implement link-level encryption and authentication between OLTs and ONUs to protect against eavesdropping, data theft, and impersonation. However, there are many choices to make and steps to follow, and the specifications do not always have a "secure by default" approach.
GPON, as the oldest PON specification in this blog post, offers the most limited security: downstream-only encryption and optional OMCI-based authentication. Without OMCI authentication, unicast data encryption keys are transmitted unencrypted to the OLT.
XG-PON and newer PON specifications (XGS-PON, NG-PON2, 50G-PON) mandate authentication and support bidirectional encryption. However, the Registration ID-based scheme will use a default null string if not provisioned: while the resulting secure channel will be authenticated and encrypted, it will be based on a known secret, which defeats the purpose of the secure channel. Only the IEEE 801.2X-based scheme with the right EAP mode (such as EAP-TLS with a Diffie-Hellman key exchange) can support Perfect Forward Secrecy (PFS), preventing "harvest now, decrypt later" attacks.
For all PON versions, encryption is usually disabled by default. Only the OMCI XGEM port is always encrypted in both directions for XG-PON and above.
Then, a block cipher (usually AES-128) is used in CTR mode for the actual encryption of the (X)GEM payloads. The CTR mode does not provide authentication of the payload, which means an attacker can blindly modify the ciphertext without being detected. AEAD modes, which are the only modes supported by TLS 1.3 for instance, provide both encryption and authentication of the payload simultaneously.
A somewhat new evolution in the PON specifications is the support of 256-bit block ciphers by the Higher Speed PON (HSP)/50G-PON specifications. 50G-PON now mandates the support of 256-bit keys, and generalises the use of ciphers of this key size. While we do not make any conclusions on the specifications' resilience against quantum cryptography, 256-bit AES keys are recommended by multiple agencies' post-quantum cryptography notes2627 as a measure against Grover's algorithm. ITU-T Supplement 8120 recommends using HMAC-SHA-256 in the OMCI-based authentication scheme for quantum-resistance.
50G-PON also changes how the unicast data encryption key is generated by including an OLT-generated value. However, the key is still generated on the ONU's side and sent to the OLT, unlike a Diffie-Hellman key exchange for instance, where the shared secret is at least guaranteed to include each sides' secret.
Moreover, 50G-PON still includes a section relative to "reduced data encryption strength", which has carried on across PON specifications since GPON. It is unclear why such a provision is still necessary when 256-bit keys have been introduced.
Finally, while we did go through a lot of PON security threats and features, there are other concerns that we did not discuss. The ITU-T specifications and supplements also mention "rogue ONUs", ONUs that do not behave according to the specification, and how to protect against them. Cloned ONUs, attacks against OMCI Management Entities, are other subjects we did not tackle.
Acknowledgments
I would like to thank my colleagues Angele Bossuat and Celian Glenaz for their review, as well as all other reviewers of this blog post!
Further reading
References
-
R. Rousseau, "Avec le 50G-PON, Orange propose une experience inedite en France et demontre la prouesse de la fibre du futur," Newsroom Groupe Orange. Available: https://newsroom.orange.com/?p=60059. &larrhk
-
ITU-T G.984.1 (03/2008) - Gigabit-capable passive optical networks (GPON): General characteristics &larrhk
-
ITU-T G.984.2 (08/2019) - Gigabit-capable Passive Optical Networks (G-PON): Physical Media Dependent (PMD) layer specification &larrhk
-
ITU-T G.984.3 (2014) Amd. 2 (11/2025) - Gigabit-capable passive optical networks (G-PON): Transmission convergence layer specification &larrhk&larrhk&larrhk
-
ITU-T G.984.4 (02/2008) - Gigabit-capable passive optical networks (G-PON): ONT management and control interface specification &larrhk
-
ITU-T G.987 (06/2012) - 10-Gigabit-capable passive optical network (XG-PON) systems: Definitions, abbreviations and acronyms &larrhk
-
ITU-T G.987.1 (2016) Cor. 1 (03/2020) - 10-Gigabit-capable passive optical networks (XG-PON): General requirements &larrhk
-
ITU-T G.987.2 (2023) Amd. 1 (06/2023) - 10-Gigabit-capable passive optical networks (XG-PON): Physical media dependent (PMD) layer specification &larrhk
-
ITU-T G.987.3 (05/2025) - 10-Gigabit-capable passive optical networks (XG-PON): Transmission convergence (TC) layer specification &larrhk&larrhk&larrhk&larrhk&larrhk&larrhk&larrhk
-
ITU-T G.9807.1 (2023) Amd. 1 (05/2025) - 10-Gigabit-capable symmetric passive optical network (XGS-PON) &larrhk&larrhk
-
ITU-T G.989 (10/2015) - 40-Gigabit-capable passive optical networks (NG-PON2): Definitions, abbreviations and acronyms &larrhk
-
ITU-T G.989.1 (03/2013) - 40-Gigabit-capable passive optical networks (NG-PON2): General requirements &larrhk
-
ITU-T G.989.2 (2019) Amd. 1 (10/2020) - 40-Gigabit-capable passive optical networks 2 (NG-PON2): Physical media dependent (PMD) layer specification &larrhk
-
ITU-T G.989.3 (2021) Amd. 2 (05/2025) - 40-Gigabit-capable passive optical networks (NG-PON2): Transmission convergence layer specification &larrhk&larrhk&larrhk&larrhk
-
ITU-T G.988 (2022) Amd. 2 (05/2025) - ONU management and control interface (OMCI) specification &larrhk&larrhk&larrhk&larrhk
-
ITU-T G.9804.1 (2019) Amd. 3 (05/2025): Higher speed passive optical networks - Requirements &larrhk
-
ITU-T G.9804.2 (2021) Amd. 3 (11/2025): Higher speed passive optical networks - Common transmission convergence layer specification &larrhk&larrhk&larrhk&larrhk&larrhk
-
ITU-T G.9804.3 (2021) Amd. 3 (02/2026): 50-Gigabit-capable passive optical networks (50G-PON): Physical media dependent (PMD) layer specification &larrhk
-
ITU-T G.9805 (2022) Amd. 2 (11/2025) : Coexistence of passive optical network systems &larrhk
-
G Suppl. 81 (ex G Suppl.PONsec) - Practical aspects of PON security - Revision 1 &larrhk&larrhk&larrhk
-
"GPON - OMCI MIB [O3 Labs]." Available: https://www.tripleoxygen.net/wiki/misc/gpon/omci-mib#privados &larrhk
-
M. J. Dworkin, "Recommendation for block cipher modes of operation : methods and techniques," National Institute of Standards and Technology, Gaithersburg, MD, NIST SP 800-38a, 2001. doi: 10.6028/NIST.SP.800-38a. &larrhk&larrhk
-
J. Vollbrecht, J. D. Carlson, L. Blunk, B. D. Aboba, and H. Levkowetz, "Extensible Authentication Protocol (EAP)," Internet Engineering Task Force, Request for Comments RFC 3748, Jun. 2004. doi: 10.17487/RFC3748. &larrhk&larrhk
-
C. Clancy and H. Tschofenig, "Extensible Authentication Protocol - Generalized Pre-Shared Key (EAP-GPSK) Method," Internet Engineering Task Force, Request for Comments RFC 5433, Feb. 2009. doi: 10.17487/RFC5433. &larrhk
-
D. Simon, R. Hurst, and B. D. Aboba, "The EAP-TLS Authentication Protocol," Internet Engineering Task Force, Request for Comments RFC 5216, Mar. 2008. doi: 10.17487/RFC5216. &larrhk
-
"ANSSI views on the Post-Quantum Cryptography transition". Available: https://messervices.cyber.gouv.fr/guides/en-anssi-views-post-quantum-cryptography-transition &larrhk
-
"Post-Quantum Cryptography: Current state and quantum mitigation | ENISA.". Available: https://www.enisa.europa.eu/publications/post-quantum-cryptography-current-state-and-quantum-mitigation &larrhk
-
π exe.dev Mayfly Chat: Transient Chat for Agents rss
Earlier this week I caught myself copy/pasting code between two agents.
I donβt want to be a meat proxy, but it really was going to be best if they justβ¦talked to each other. And yet it was weirdly hard to arrange that.
So I summoned Mayfly Chat.
Thereβs not much to it. It provides transient chat channels for agents. You click βNew Channelβ and then give the URL to your agents, and then they can chat there. You can watch or chime in if you want.
Use Cases
The instant I had my first prototype up I suddenly had a dozen use cases.
For example, on one of my systems, I had an agent rearranging some dotfiles and doing some configuration, and I wanted the same thing to be replicated on another of my computers, which had a somewhat different base configuration. Instead of having to figure out how to systematize it, which was really not worth the time, I started a new agent on the second machine and asked the first agent to guide it on what the new configuration should look like. Communicating over Mayfly Chat, the two agents worked together to adapt the setup to the shape of the second machine in a way that would have been pretty tedious to do through scripting.
Later, I found that some code that I had developed on one machine needed specialized access to a service conveniently available from a VM. No problem. Spin up a second agent on the VM, get them both in a chat, give them both their brief, and let them work it out together.
It's like having a subagent, only the subagent runs anywhere you like.
Mayfly Chat supports having a large number of participants. Farming out a task to a little swarm? Ensure they all have the channel URL up front, and watch them sort it out together.
Yet another use case: I started an agent on a little server in my house but had to step away from my LAN. I wanted to keep communicating with it from my phone, so I set up a channel and used that.
Yes, most of these use cases would be obviated by better planning. Sounds nice. But alsoβ¦hahahahahahaha.
Oh, and of course, agents can create Mayfly Chat channels too. What could go wrong.
Security
The hardest design aspect was the security and privacy model. My initial prototype sent everything in cleartext with simple curl commands.
It was easy to use and easy to explain, and it just worked. And if you completely control all access to the server, that's fine. But I wanted to be able to stand this up as a public service for folks who wanted to kick the tires or just plain didn't want to run their own.
I didn't want anybody else's readable data anywhere near my VM, which meant end-to-end encryption was a hard requirement.
Of course, end-to-end encryption requires that the client actually do some real work, not just send a curl command. And I wanted using Mayfly Chat to involve no setup for the human and no thick client libraries. The whole point was to be lightweight.
The solution: Hand the agents a small script that they could use to do the end-to-end encryption. This should terrify you. Wait, you say. Your server is going to solve its security problem by handing out code to my agents? Yes. Yes it is.
There is already a variant of this problem with any browser-based end-to-end encryption. The server serves you the JavaScript that you feed your data into, and the server can just send you different JavaScript. Our world fundamentally runs on trust, and anyone who says otherwise is trying to sell you cryptocurrencies.
(Remember: end-to-end encryption here is solving my problem of not wanting to have your data. To solve your problem, namely having to trust the server, you can and should run your own. It is open source! I made it intentionally easy to deploy. You might even choose to deploy it on exe.dev. But failing that, you may also decide to just trust me.)
The alternative to these scripts was to describe the protocol in detail and make every single agent re-implement their own client. For something that is supposed to be speedy and disposable, that was going to be too slow and token- hungry.
So I selected an end-to-end encryption scheme that was as small and lightweight as possible, so that the actual scripts are extremely auditable, including by the agents grabbing them. Will the agents actually audit it? I dunno, probably not. But in principle they should be able to readily spin off a subagent, glance at a very moderate amount of mundane code, and convince themselves readily that it is not malicious and does exactly what it says on the tin.
This requirement precluded fancier forms of encryption like, say, the Signal protocol. I'm still not super happy about it, but between the Scylla of clear text and the Charybdis of client support, I will take the client support. I had hoped that there were existing widely distributed unix tools that could be chained together to accomplish what I wanted, but I couldn't find any. (If you know of some, please let me know, and I will happily retrofit them in!)
Another tricky question was permissions boundaries. For example, if an agent joins the conversation late, should it be able to see the history of all the messages to date or only the new ones? I eventually realized that it didnβt matter. Anyone who joins the conversation late can simply ask one of the agents to catch them up on everything that happened so far, and that agent will happily comply.
By far, the best thing to do in this scenario is to have a very simple, very honest mental model, which is: once you have the URL, you have root. Every client is equally privileged. Every client can read everything. It can post; it can lie about its identity; it can delete the thread. Anything else is theater, and this model is easy to reason about.
The last sticky point was metadata. Itβs always metadata. And I basically punted. The server has metadata. And more than that, I made one conscious decision to store and forward client IP addresses. The server is in a unique position to have unspoofable knowledge of the IP address, unlike the data. By forwarding it along, if an agent suddenly has a different IP address, there is at least a little chance that one of the other agents might notice. And if you notice, you can at least assess, is that IP address a plausible one? On balance, I felt that the value to the user of the service warranted having the IP address stored in the clear alongside the other metadata.
I'm sure that other people would make different choices about security and privacy than I would. That's fine. Code is cheap now.
I have shared the idea with you. Go forth and make your own transient chat that matches your exact needs. Fork Mayfly Chat if you feel like, or start from scratch. And if you just want to use the hosted version https://mayfly.chat/, it's at your disposal.
-
π anthropics/claude-code v2.1.273 release
What's changed
- Added
x-claude-code-request-class,x-claude-code-agent-type,x-claude-code-prev-tool-durations,x-claude-code-compactionandx-claude-code-context-compactedrequest headers for LLM gateways; opt in withCLAUDE_CODE_GATEWAY_HINT_HEADERS=1 - Added a notification when an MCP server disconnects mid-session and automatic reconnection gives up, pointing at
/mcp - Added forking a session started with
claude --remote-controlor/remote-controlfrom the Claude app; the fork runs as a background session on your computer - Fixed Bash commands the permission checker cannot fully analyze skipping the prompt under
permissions.blockReadsOutsideWorkingDirectories, and a subshell hiding a dangerousrmin bypass mode - Fixed skills synced from claude.ai staying available after your organization turns Skills off; they now move to the recoverable trash
- Fixed
allowManagedMcpServersOnly,deniedMcpServersanddisableClaudeAiConnectorsset via MDM ormanaged-settings.jsonbeing ignored when server-managed settings are also present - Fixed 401/403 errors on Bedrock, Vertex and Foundry, and Claude apps gateway 403s, telling you to run
/login; the message now names the credential to refresh or points to your gateway administrator - Fixed
/login,/upgrade, and/extra-usagediscarding earlier thinking from the conversation, which forced a full prompt-cache rewrite on the next request - Fixed auto mode stopping for approval when the Artifact tool uploads a file you attached to the chat in a cloud or Remote Control session
- Fixed a long-running session recreating a stub
.git/info/excludeafter the repository's.gitdirectory was removed or moved away - Fixed the main prompt dropping a
!typed at the start while already in shell mode, so negated commands like! grep β¦can be typed - Fixed Read on macOS refusing a dragged-in screenshot, or any file the system reports under a second path, with "symlink resolution changed after permission was checked"
- Fixed
permissions.blockReadsOutsideWorkingDirectories: a memory directory chosen by a repository's settings is no longer loaded into the prompt, recalled, indexed, or used by memory extraction - Fixed sub-agents and background agents being reported as failed, with their result never delivered, when the final streamed reply omitted token usage or carried no model id
- Fixed the context meter and auto-compact counting advisor-tool turns at roughly twice their real context size, which made auto-compact fire at about half the real window
- Fixed
/tuirefusing to restart because of an agent-team teammate that had already finished its work and was no longer shown in the agents panel - Fixed saved scheduled tasks running in the wrong session after
.claude/scheduled_tasks.jsonwas copied into another folder, such as a new worktree - Fixed SDK and
--output-format stream-jsonoutput dropping a subagent's remaining messages and final report after it is moved to the background mid-run (e.g. byCLAUDE_AUTO_BACKGROUND_TASKS) - Fixed
/install-github-appreporting a SAML single sign-on block as "admin permissions required" - Fixed Remote Control clients attached to a Claude Desktop, VS Code or JetBrains session being refused when they ask for the session's context window usage
- Fixed the spinner showing a doubled ellipsis ("β¦β¦") on compaction status lines such as "Running PreCompact hooksβ¦"
- Fixed a false-positive spinner tip suggesting the frontend-design plugin after reading or publishing Artifacts
- Reverted a 2.1.268 change that checked Read and Edit deny rules on Bash lines the permission checker can't analyze (
eval,env -C); commands liketime -p make buildprompt again instead of being denied - Improved responsiveness in long sessions: hook progress and sub-agent activity no longer re-process the whole conversation on every update
- Improved the Artifact tool's error when a publish includes a file type artifacts don't serve: Claude is told which types are served and what to do instead, and the terminal shows one plain line
- Improved the Artifact tool's page read to state the capabilities and database rules the artifact service holds for the page, for anyone who can publish to it
- Improved artifact database writes: an update can now remove a single field instead of rewriting the whole document
- Improved artifact publishing: a publish whose connection drops after reaching claude.ai is now re-sent safely instead of failing or creating a duplicate version
- Improved the cloud-session GitHub error for an IP allow list, a suspended app installation or SAML single sign-on to show the cause instead of a generic install hint
- Improved
/autofix-pr: whengh pr viewfails it now shows gh's own error (sign-in, SAML, rate limit) instead of a generic exit-code line - Improved
/autofix-prto say why GitHub webhook delivery couldn't be set up for the PR (for example, no linked GitHub account) instead of a generic warning - Improved
/web-setuperrors: a refused GitHub token now lists the likely reasons and the fix, and a connection failure names a configured proxy or TLS certificate problem - Improved the in-session SSL certificate and proxy connection errors to name the error code and what to fix, such as
NODE_EXTRA_CA_CERTSfor an untrusted corporate CA - Improved the error when a cloud session can't be created because your Claude login expired or was revoked: it now tells you to run
/login - Improved the error shown when an MCP server's sign-in expires mid-session to say how to re-authenticate (
/mcp) - Changed auto mode on Bedrock, Vertex and Foundry to use the local classifier by default for now; set
CLAUDE_CODE_AUTO_MODE_SERVER=1to use the platform's server-side classifier - Changed
OTEL_LOG_TOOL_DETAILS=1to also include real agent, skill, plugin and MCP server names on cost and token metrics - Changed sign-in with a Claude account to also request access to your claude.ai plugins
- Changed
/bugand/feedbackreports to include only model-behavior params (model, system prompt, tools) from the last API request, omitting request metadata andCLAUDE_CODE_EXTRA_BODYfields - [VSCode] Fixed "Report a problem" still appearing, and
/bug//feedbackopening a report form, for organizations that have product feedback disabled - [VSCode] Fixed a red "Claude Code process exited with code 4294967295" banner appearing after completed turns on Windows
- Windows: Improved the network-path permission check for UNC paths when a mapped network drive was added with
--add-dir - [Claude Code on the web] Fixed routines losing access to an organization connector, and still calling the old one, after an admin removed and re-added that connector
- [Claude Code on the web] Fixed creating a self-hosted environment from organization settings occasionally failing with a server error and leaving a half-created environment behind
- [Claude Code on the web] Changed the admin "Share cloud sessions" setting to live under Data and privacy instead of the Claude Code page, where Data and privacy admins can also manage it
- [Claude Code on the web] Added a "Discard unsaved changes?" confirmation before the New routine page or the Edit routine dialog throws away a routine name, prompt or edit you typed
- [Claude Code on the web] Removed the full-page desktop-app download screen that new users without a cloud environment saw on Mac and Windows; they now go straight to setup
- [Claude Code on the web] Improved the routine detail page: menu and rename in the breadcrumb, the on/off switch and Run now at the top, and run history beside the routine's settings
- [Claude Tag] Fixed Claude going silent minutes after reinstalling the app when an Enterprise Grid was disconnected but one of its workspaces stayed connected
- [Claude Tag] Fixed scheduled tasks set up in an organization-shared private Slack channel silently never posting; they now keep running in the thread they were created in
- [Claude Tag] Fixed replying in an older Slack thread while Claude is mid-task sometimes restarting it from scratch and losing work it had not pushed yet
- [Claude Tag] Fixed Claude occasionally dropping a message with an incorrect "couldn't find a Claude Code environment" notice right after your account token refreshed
- [Claude Tag] Fixed AWS connections refusing region-less endpoints such as Budgets, Savings Plans, WAF Classic and Import/Export; Global Accelerator requests now sign correctly
- [Claude Tag] Improved AWS connection failures: when a request can't be signed, such as a hostname with no region, Claude is told why and how to fix it instead of a bare error
- [Claude Tag] Fixed OAuth client-credentials and JWT-bearer connections failing with providers that return a lowercase token type; requests now send the standard Bearer scheme
- [Claude Tag] Fixed adding a channel manager being refused on Enterprise Grid shared channels, on channels where Claude hasn't been used yet, and on legacy private channels
- [Claude Tag] Changed Claude to start watching related public channels on its own, such as an incident channel a conversation depends on, instead of only when asked
- [Claude Tag] Fixed the admin Memory page not listing Slack channels Claude set up on its own even when they had saved memory; admins can now open, edit and delete that memory
- [Code Review] Fixed merging the base branch into a PR whose earlier review listed "Additional findings" triggering a full re-review; these pushes now get the lighter follow-up review
- [Code Review] Fixed a whole REVIEW.md being ignored because of an @-mention, a code span wrapped across lines, or a backticked HTML tag; only lines linking to changed files are withheld
- [Code Review] Improved suggested fixes to say what the fix must keep working when other code depends on the behavior being changed
- [Code Review] Improved review comments that point to a second affected location to state that location's issue in a full sentence instead of a cut-off stub
- [Code Review] Fixed
/ultrareview --postso a retry after a GitHub error posts the findings comment exactly once instead of never or twice; the comment now names the reviewed commit - [Code Review] Fixed empty or content-identical pushes being re-reviewed on GitHub repositories whose owner or name contains a capital letter; these pushes are now skipped
- Added
-
π Locklin on science Developing immunity to propaganda rss
Propaganda is one of those things which has obviously improved in its execution over time. In part this is due to higher levels of education among the populace. Educated people are used to stuffing facts in their brains, and continue the habit after the formal education has ended. This is what propaganda is: stuffing unverified […]
-
π backnotprop/plannotator v0.27.15 release
Follow @plannotator on X for updates
Missed recent releases? Release | Highlights
---|---
v0.27.14 | Pi plan progress survives compaction, Codex threads across rollout files, WSL browser setting, Mod+E edit mode
v0.27.13 | Open a review on a specific base (--base,--diff-type), symlink containment on /api/doc, CI flake fix, Amp decision relay
v0.27.12 | Unified decision control, token hover cards, local-vs-remote diff, approval notes
v0.27.11 | OpenCode server leak fix, durable local feedback archive, unknown-subcommand fix
v0.27.10 | Auto-viewed files on scroll, annotation undo/redo, OpenCode 2 slash commands restored, npm 12 agent terminal fix
v0.27.9 | WebMCP browser-agent tools, HTML refresh from disk, host seams, lazy renderers, Windows uninstall fix
v0.27.8 | Pi keeps its prompt cache across plan transitions, thumbs-up returns to HTML annotation, embed picker seam
v0.27.7 | Pi host crash fix on Windows, Call Flow tree cap, jj fork-point base, plannotator knowledge skill + llms.txt
v0.27.6 | Live app annotation lands on Pi, one interaction model for HTML pages
v0.27.5 | Annotate your running app, Agent TUI placement, collapsed lockfiles, VS Code theme fix
v0.27.4 | Portable Guided Review exports, guides.show share links, guide CLI, jj Call Flow
v0.27.3 | Folder watcher freeze fix on large repos, first SBOM-attested release pipelineWhat's New in v0.27.15
Twenty-six pull requests, three of them from outside contributors and two of those first contributions. Most of the work is on the HTML annotate surface: pinpoint comments now carry a description of the element they point at, the page gets the whole viewport by default, links between local HTML files stay inside the session, and a folder review can finally see every comment it has collected. The rest is correctness work on annotation restore, on the Codex Stop hook, on the OpenCode 2 notice ordering, and on the x64 release binaries.
Four behavior changes are worth reading before you update: HTML annotate sessions now open with the floating tools hidden, the plan diff opens in Classic view again, an emoji on a GitHub alert's first line becomes that alert's icon, and Codex 0.114 through 0.116 users now get plan review on Stop where they previously got nothing.
Plannotator TUI and Herdr Annotate
A one-time panel now announces Plannotator's two terminal tools. Plannotator TUI is a standalone terminal client: annotate Markdown in the terminal (select, comment, looks good, delete), review a folder, or annotate one of your agent's recent replies, then hand the review to your agent as numbered feedback. Herdr Annotate is a Plannotator plugin for Herdr: comment on any terminal text, review Markdown documents and agent replies inside Herdr, and send the feedback straight back to the agent. Its document review runs Plannotator TUI.
The panel shows a looping demo of the real client, one headline, one sentence, and a row of actions. It appears once per browser across plan review, annotate, and code review, then never again. There are no install commands or feature lists in it; the repo pages carry those. It is also suppressed in sessions that have no server behind them, so the public share portal never shows it.
The repos are plannotator-tui and herdr-annotate.
Pinpoint comments describe the element to the agent
Pinpointing an element in a raw HTML or live app session used to export either a placeholder quote (
Feedback on: "[element: Navigation]") or the element's flattened text. The bridge already knew the element's selector, tag, and text, but nothing in the export read them, so an agent receiving the feedback could not tell which element the comment was about.Each pinpoint now captures a bounded description of the element at click time: tag, id, author-written classes, an ancestor path, ARIA role and accessible name, an allowlisted set of attributes, the rendered text, a collapsed HTML skeleton, the child count, the viewport box, the nearest landmark and heading, a component hint from
data-componentordata-testid, and in live app sessions the route and page title. The export prints that skeleton as a fenced block under the comment with the selector, path, role, name, attributes, and box beneath it, so the agent can find the element in the source.The capture is deliberately narrow. Form values, inline
on*handlers,style, script and template contents, and full innerHTML are never read. URLs in captured attributes lose their query and fragment, both absolute and relative, so a checkout link carrying a session token is not written into a draft or an exported comment. Everything is re-validated and re-capped when it crosses back out of the iframe, and the whole record is hard-capped at 2 KiB per comment, so a 400-row list costs the same bytes as a button. Annotations without the field export exactly as they did before.HTML annotate: the page gets the viewport, and the chords are real
Three changes to the raw HTML surface, all from owner feedback while using it.
Tools are hidden on open. An annotated HTML page owns the full viewport now, with no floating chrome over it on a fresh session. The header eye shows them, and so does the new
Mod+Shift+Xchord. A reviewer who explicitly shows the tools keeps them next session, and the control that brings them back lives in the header, so a hidden state can never strand you. One consequence to know: the version diff's "Show changes" control lives in that floating cluster, so on a fresh session it is behind the eye.Mod+Shift+Ais a documented toggle. It was already wired as one in the app, but the shortcut registry and the docs described it as a re-arm only, which left "Escape dropped me to Interact, how do I get back?" unanswered. It is now described and tested as the toggle it is, and the bridge mirrors both chords from inside the sandboxed iframe, so they work whichever document has focus.The header controls explain themselves. Back, Refresh, the eye, and the pen now carry tooltips with a description line and their keyboard shortcut instead of a bare title string.
Links between local HTML files open as linked documents
A srcdoc document has no URL of its own, so it inherits the parent page's. A plain
<a href="01-entry-point.html">inside an annotated HTML file therefore resolved against the Plannotator server, the catch-all route answered with the app's own HTML, and the entire editor rendered inside the annotated frame. Even an in-page#anchordid it.Link clicks are now intercepted in the bridge and resolved in the parent. A relative or nested sibling opens as a linked document in place, with its annotations kept per document. An in-page fragment scrolls within the current document. A server-absolute path resolves against the directory the session opened from. A sibling markdown file opens as a markdown document. An off- origin link opens in a new tab with
noopener. A file that cannot be annotated gets a toast and no navigation, andjavascript:,data:,mailto:andfile:are dropped. Live app sessions are untouched.The way back is a new header control, leftmost of the group, named after the document it returns to. It claims no keyboard chord, because
Alt+Leftand the browser's own Back belong to you. The compact touch shell gets the same action in its Options menu. Link clicks no longer pop the sidebar open on HTML documents, since a full-screen page owns the viewport and the sidebar is not where the way back lives anymore.All files view in the annotations panel
In a folder session the annotations panel only ever showed the open file's comments. Reviewing across several documents, there was no way to see the whole review, and a file with nothing on it showed "No annotations yet" beside a small count of comments elsewhere that you could not read.
The panel header now carries a
This file | All filestoggle, shown whenever feedback exists outside the open document. All files groups comments by document, open document first and the rest by path, each group collapsible and labelled relative to the session root. The groups render the same annotation cards the single-document timeline renders, so quote, comment, type, images, replies, Edit and Delete all work across files, and a cross-file delete is reflected in what gets submitted. Clicking a card navigates to that document and selects the comment there.The default rule is the frustration this exists for: your saved preference wins, except that a document with no feedback of its own, while other documents have some, opens on All files. Arriving by clicking a card in the All files list keeps you on All files. A plan review session with linked documents open contributes the plan's own comments as a group too, labelled
(this plan).GitHub alert titles, and the annotation restore work that followed
A GitHub alert whose first body line is a bold-only line now renders that line as the alert's title on the icon row, in place of the type word. An emoji on that line becomes the alert's icon, which is the behavior change to know about:
> [!TIP]followed by> π‘ **Browser quirks**now shows the lightbulb and the title rather than the default tip icon and a bold paragraph. The type word stays in the accessible name, so a screen reader still hears "Tip: Browser quirks". An alert with no title line renders exactly as before. Hosts embedding the UI can supply their own icon set through a newalertIconRendererseam; Plannotator bundles none.That change removed a paragraph from the rendered alert, and the annotation layer addresses blocks by position. A draft saved before the upgrade could resolve onto the wrong element, so restore verification was turned on for plan review and annotate: a restore whose painted text does not match the annotation's own quote is dropped and retried by text search, and only reported when the rescue also fails. That guard then turned out to be too strict, and the next two releases of work fixed what it broke and what it had been hiding.
Restore verification compared the stored quote against the painted text with whitespace collapsed to a single space, but a selection string carries a blank line between blocks and the painted marks are concatenated with nothing between them. Every annotation spanning two paragraphs, a heading and its paragraph, or two list items came back from a reload with no highlight at all, under a misleading toast about edited text. Whitespace-only differences are now accepted, and content drift is still rejected. Two more shapes were failing closed for their own reasons: a drag starting inside excluded chrome, such as an alert's visually hidden type word, painted only its tail, so the start of a range is now snapped onto the first annotatable position it covers; and list markers are
select-none, so a selection spanning two list items resolved onto text the bullet had joined, which the verification then rejected.The other half of this is that an annotation that genuinely cannot be re- anchored is now visible on markdown surfaces the way it already was on HTML: the comment stays in the panel, still exports, and carries an Unanchored chip so you know its highlight is gone rather than wondering where it went.
- #1509 and #1511 (alert titles, icon seam, accessible name on WebKit), #1535, #1541, and #1542 (restore hardening)
Comment box caret alignment on Windows and Linux
The comment composer paints its visible text with a mirror layer over a transparent textarea, and only the caret still comes from the textarea itself. When the textarea grew tall enough to sprout a classic vertical scrollbar, the kind Windows and Linux use, which consumes layout width, the textarea's lines wrapped earlier than the mirror's. From the first line whose wrap point differed, the caret was drawn away from the character it belonged to. macOS and iOS overlay scrollbars take no layout width, which is why nobody on a Mac ever saw it.
The overlay's right padding now tracks the measured scrollbar width, re- measured when a resize adds or drops the scrollbar rather than only on keystrokes. Where the measured width is zero, the code writes no inline style at all, so macOS, iOS, and every touch surface render a byte-identical DOM to before.
Classic is the plan diff default again
The plan diff opens in Classic view, the block-level view with old above new. The word-level Rendered view is still there next to Raw. This applies to every surface that renders the plan diff, including the annotate version diff, since they share one mode setting.
OpenCode 2: feedback no longer lands behind the session notice
On OpenCode v2,
/plannotator-lastprinted "Plannotator session ready: " and the agent correctly stayed idle. When the reviewer clicked Send Feedback, the agent woke up and spent a whole model turn on the URL notice first, with the annotations arriving in the turn after it. A plugin's synthetic message is not a notification on OpenCode 2: it admits a pending inbox row, and declining the wake does not exempt that row from the next promotion. Since queued rows promote one at a time, oldest first, the reviewer's own feedback was what woke the session and pulled the stale notice ahead of it.The notice and the feedback that follows it now share one promotion, so they enter the same turn. Two follow-ups hardened the tracking behind that. The first made the pending flag track reality instead of intent: it was set when the host accepted the notice and cleared only after our own prompt, so a reviewer who typed anything in the TUI while the review was open had the notice promoted out from under the flag, and feedback sent minutes later was steered into the middle of an unrelated turn. The flag is now cleared when the host reports the row left the inbox, read in both event vocabularies OpenCode 2 uses, after which feedback falls back to queued delivery. The second made the tracker's
dispose()terminal, so a notice that outlives its command cannot re-open an event subscription on the host with no owner left to close it. OpenCode 1 is untouched throughout.Codex: Stop plan review stays in the current turn
The Codex Stop hook could scrape the most recent
<proposed_plan>out of the rollout even when the turn that just ended proposed no plan, which resurfaced a plan from an earlier turn and opened a second review of something already decided. Plan candidates are now confined to the turn the Stop payload identifies, and the hook fails closed when turn identity is unavailable rather than guessing from stale transcript content.That fix assumed every Codex sends a turn id with its Stop payload. It does not. The hooks engine shipped in Codex 0.114 and the
turn_idfield only landed in 0.117, so on 0.114 through 0.116 plan review silently stopped: no UI, no message, exit 0. Those versions do write turn markers into the rollout, so when the payload carries noturn_idat all the hook now resolves the turn from the rollout's own last id-carrying marker and runs the unchanged machinery on it. Codex builds that do sendturn_idbehave byte for byte as before. A blank turn id is still refused rather than treated as absent, and a rollout with no turn marker at all still fails closed.The deny-and-resubmit de-duplication needed the same treatment. It anchored on a
<hook_prompt>user message that Codex only started writing in 0.117, so on exactly the versions the rollout fallback exists to support, a reviewer who clicked Request changes got the unchanged denied plan re-opened whenever the model replied without a fresh plan. The boundary is now whatever the previous blocking Stop left in the turn, accepting Codex's older developer-role continuation message on the rollout-fallback path only.Pi: PLANNOTATOR_BROWSER script paths work on macOS
On macOS the Pi extension always ran
open -a $PLANNOTATOR_BROWSER <url>, treating the value as an application bundle. Pointing it at a script or an executable failed with a LaunchServices error that the detached spawn swallowed, so the extension reported that the review had opened while nothing did. Pi now mirrors the branch theplannotatorbinary already had: a value containing a slash that does not end in.appis executed directly with the URL as its argument, and application names and.apppaths keep going throughopen -a.- #1429 by @punk-dev-robot, closing #1391, which he also reported and @rNoz helped diagnose
x64 release binaries run on older CPUs
The v0.27.14 Linux x64 CLI exited with SIGILL on an Ivy Bridge Xeon E3-1220 V2, because the default Bun x64 target assumes instructions those CPUs do not have. The Linux and Windows x64 CLI and paste service binaries are now compiled with Bun's baseline x64 target, which Bun recommends for pre-2013 hardware. A bounded QEMU Nehalem gate was added to the existing Linux release smoke job, checking CLI
--help, an exact--versionmatch, and paste service startup, so a non-baseline binary fails the release rather than reaching someone's machine. Asset names, checksums, provenance attestations, the installers, the Bun pin, and every other platform target are unchanged.Additional Changes
- Annotation panel chrome. The header decision button reads
Send Feedbackrather thanSend Feedback Β· n, and the per-row Copy button briefly added to annotation cards is gone; cards are back to Edit and Delete on every surface. Both owner-directed (#1516, #1520) @plannotator/uipackage publishes. 0.38.1 on core 0.25.2 fixes an install failure for embedding hosts: 0.38.0 imported a core subpath that had never been published, and the package smoke test now catches that class of break by checking the source imports against the published core. 0.38.2 restores the alert type word in the accessible name on WebKit and relaxes the React peer range back to^19.2.3. 0.39.0 carries the element context types and parser helpers (#1510, #1511, #1522)- DOM tests actually run in CI. Forty-two DOM-gated test files had drifted off the workflow's explicit list and were silently skipping. They are registered now, along with a guard test that fails whenever a DOM-gated file in the repo is not named in a DOM_TESTS step (#1537, #1538)
Install / Update
macOS / Linux:
curl -fsSL https://plannotator.ai/install.sh | bashWindows:
irm https://plannotator.ai/install.ps1 | iexClaude Code Plugin: Run
/pluginin Claude Code, find plannotator , and click "Update now".Pi: Update
@plannotator/pi-extensionto 0.27.15 and restart Pi.OpenCode: Clear cache and restart:
rm -rf ~/.bun/install/cache/@plannotatorWhat's Changed
- feat(ui): render a GitHub alert's bold-only first line as its title, with an icon seam by @backnotprop in #1509
- fix(packages): core 0.25.2 + ui 0.38.1, and a package smoke that catches an unpublished core subpath by @backnotprop in #1510
- fix(ui): keep the alert type word in the accessible name on every engine (ui 0.38.2) by @backnotprop in #1511
- fix(ui): drop the annotation count pill from the header decision primary by @backnotprop in #1516
- feat(annotate): carry agent-facing element context on HTML and live-app pinpoints by @backnotprop in #1517
- fix(opencode): co-promote the session-URL notice with the feedback on OpenCode 2 by @backnotprop in #1518
- fix(ui): remove the annotation panel's per-row Copy button by @backnotprop in #1520
- chore(ui): bump @plannotator/ui to 0.39.0 by @backnotprop in #1522
- feat(ui): one-time announcement dialog for Plannotator TUI and Herdr Annotate by @backnotprop in #1529
- fix(codex): keep Stop plan review in the current turn by @rNoz in #1169
- fix(pi-extension): run script/executable PLANNOTATOR_BROWSER paths directly on macOS by @punk-dev-robot in #1429
- fix(ci): build x64 releases for baseline CPUs by @ybtam in #1514
- fix(ui): keep the composer text overlay aligned with the textarea when a classic scrollbar appears by @backnotprop in #1530
- feat(annotate): hide HTML tools by default, toggle chords for annotate mode and tools, shortcut tooltips on the header controls by @backnotprop in #1531
- fix(annotate): open relative links between HTML files as linked documents instead of loading the app inside the frame by @backnotprop in #1532
- feat(annotate): All files view in the annotations panel for folder sessions by @backnotprop in #1533
- fix(codex): resolve the current turn from the rollout when the Stop payload carries no turn_id by @backnotprop in #1534
- fix(opencode): track whether the session-URL notice is still pending before steering feedback by @backnotprop in #1536
- fix(annotate): QA follow-ups for the folder, All files, and HTML surfaces by @backnotprop in #1537
- fix(ui): keep GitHub alert titles from breaking annotation anchors and quotes by @backnotprop in #1535
- ci: register the #1535 DOM tests in the allowlist by @backnotprop in #1538
- fix(codex): keep deny/resubmit de-duplication working on the rollout-fallback path by @backnotprop in #1539
- fix(opencode): make the notice tracker's dispose terminal by @backnotprop in #1540
- fix(ui): accept whitespace-only differences in restore verification, snap excluded selection starts, and merge folder-session chrome re-stamps by @backnotprop in #1541
- fix(ui): restore cross-block annotations over list markers and alert titles from drafts by @backnotprop in #1542
- fix(editor): default the plan diff view to Classic by @backnotprop in #1544
New Contributors
- @punk-dev-robot made their first contribution in #1429
- @ybtam made their first contribution in #1514
Contributors
@rNoz returns with the Codex Stop turn scoping in #1169, the fix that stops a decided plan from being re-opened by a later turn. It is his tenth merged pull request on the project, and the two follow-ups in this release both build directly on the machinery it introduced. He also helped diagnose the Pi browser failure on @punk-dev-robot's issue.
@punk-dev-robot reported the silent
PLANNOTATOR_BROWSERfailure on macOS in #1391 and then fixed it in #1429, matching the branch the main binary already had rather than inventing a second behavior. First contribution.@ybtam found that the official Linux x64 binary would not start on an Ivy Bridge Xeon, tracked it to the Bun compile target, and shipped the baseline build with a QEMU Nehalem gate in #1514 so the failure cannot ship again. First contribution.
The reports and proposals that shaped this release:
- @de-tre reported the misaligned comment caret in #1525, with the scrollbar observation that made the root cause obvious
- @Naasha reported the queued annotations on OpenCode v2 in #1515
- @jpvarbed reported plan review re-opening for an already-decided plan in #1075
- @tekumara wrote a detailed proposal and mock for a unified review navigator in #1524. It was built in full and compared side by side against the current panel, and the current Tree / Git status / Commits design was kept; the branch is available to anyone who wants to take it further
- @JcMinarro asked for review-level comments in #1527 and, in finding that the button already existed since v0.27.12, made the case that it is placed where people do not look for it
Thank you. Plannotator gets better because you tell us where it falls short.
Full Changelog :
v0.27.14...v0.27.15 -
π HexRaysSA/plugin-repository commits sync repo: +4 releases, -2 releases rss
sync repo: +4 releases, -2 releases ## New releases - [IDAssist](https://github.com/symgraph/idassist): 2.4.0 - [ida-nexus](https://github.com/hexrayssa/ida-nexus): 0.11.1 - [ida-settings-editor](https://github.com/williballenthin/ida-settings): 1.2.4 - [llm-explainer](https://github.com/pgarba/ida-llm-explainer): 1.14.0 ## Changes - [IDAssist](https://github.com/symgraph/idassist): - removed version(s): 1.3.0 - [ida-codemode](https://github.com/hexrayssa/ida-codemode): - removed version(s): 0.3.2 -
π smol-machines/smolvm smolvm v1.16.1 release
What's Changed
- Speed up pack compression with bounded zstd workers by @BinSquare in #1243
- Fix checkpoint restore port collisions and startup diagnostics by @BinSquare in #1248
- Reuse cached image layers for offline exports by @BinSquare in #1244
- Allow retrying machines after failed image pulls by @BinSquare in #1250
- Fix exports from stopped branches by @BinSquare in #1251
- Size the pack extraction cache from the disk instead of a fixed 5 GiB by @BinSquare in #1249
- Bundle sparse branchable memory promotion by @BinSquare in #1252
- cuda: expose VMM allocation APIs to PyTorch by @BinSquare in #1256
- Stream checkpoint artifacts without redundant file passes by @BinSquare in #1253
- Avoid redundant checkpoint RAM copies on Linux by @BinSquare in #1257
- Keep packed image extraction out of metadata queries by @BinSquare in #1261
- Quiesce guest storage before graceful shutdown by @BinSquare in #1260
- Map shared image layers into export helpers by @BinSquare in #1258
- Restore prepared checkpoints safely from the node cache by @BinSquare in #1259
- Expose workload image in machine responses by @BinSquare in #1262
- Clean up cancelled checkpoint captures by @BinSquare in #1263
- Update rustls to address RustSec advisory by @BinSquare in #1268
- Keep machines responsive and recoverable while checkpoints save by @BinSquare in #1269
- Fix failures when restoring the same checkpoint concurrently by @BinSquare in #1272
- Keep checkpoint restores isolated under private service permissions by @BinSquare in #1276
- Avoid connection delays after restoring a machine by @BinSquare in #1273
- Accept published-port connections without polling delays by @BinSquare in #1274
- Complete partial writes when copying checkpoint disks by @BinSquare in #1277
- Share immutable checkpoint disks between restored machines by @BinSquare in #1278
- Prepare SmolVM v1.16.1 for release by @BinSquare in #1280
Full Changelog :
v1.16.0...v1.16.1 -
π r/LocalLLaMA Qwen3.8-27B-TURBO-Fable-Cold-Fusion-735-882-Heretic-Uncensored-NEO-CODER-MAX-MTP-GGUF rss
| it be like that submitted by /u/Every-Walrus
[link] [comments]
---|--- -
π r/LocalLLaMA CrofAI "cheapest inference provider in the world" gets exposed as an OpenRouter wrapper, routing requests to smaller, cheaper models at up to 20x markup. CrofAI responds to Wire Fraud allegations by denying everything, then backtracking, then 3 hours later wiping their entire online presence rss
Disclaimer: no AI was used whatsoever to write this post
Cautionary tale about chasing cheap tokens.
exposΓ©: https://kendell.dev/blog/crofaifalse/
reaction by nahcrof, announcing the shutdown of the service: https://x.com/nahcrof/status/2099552389434900643 - now deleted, archive picture: https://i.imgur.com/teOQngH.png
NahCrofAI (crof.ai, nahcrof.com) was an inference provider which had all the latest models at the cheapest price, often significantly below the lowest alternative on OpenRouter. The owner claimed that they are running custom inference engines that allows them to offer tokens for dirt cheap, and other providers are suffering from "skill issues", that's why they are so expensive.
In reality:
-
"CrofAI is an OpenRouter wrapper that silently routes to cheaper or weaker models than what you request"
-
For example, expensive models like
kimi-k3are sold at $2/$10 in/out, but instead routed toGLM 5.3 Flashvia OpenRouter, representing a 13.3x multiple on input, and 20x multiple on output -
CrofAI's "own model family"
greg-2-ultraroutes to GLM 5.2,greg-1-miniroutes to Qwen 3.5 9B.greg-2-super,greg-1,greg-1-superroutes to Kimi K2.7 Code. All of these at a significant markup compared to the actual model being served. CrofAI admits in DMs that his claims of thegregfamily being made by him is a lie. -
The person investigating details the 5 different attempts by CrofAI at fixing their models being served via OpenRouter after given a heads-up and a lengthy grace period. In all 5 attempts, the only change CrofAI made was attempts to hide the fingerprints of OpenRouter, while still serving models through them
-
Other inconsistencies don't add up either: CrofAI claims to run Kimi K3 on RTX Pro 6000s rented via Vast. That model requires ~802GiB even at the lobotomy level quantization of Q2_K. The largest RTX PRO 6000 machine on Vast has only 8 of them, totaling 765GiB. He also claimed that for the purposes of "investigating" the "issue" of his API routing to OpenRouter, he will have deepseek-v4-flash-0731 running on his local DGX Spark. A Spark has 128GB memory, and is therefore unable to run that model.
CrofAI responded to the exposΓ© by announcing the shutting down of their service; after their failure to provide their own inference, they promise to provide one last thing: a refund to those asking.
UPDATE
UPDATE: around 4:30 AM UTC of Sept 15, the owner published a now-deleted blog post (archive image) writing under the fake pretense that it's his "team" authoring it, stating all of CrofAI founder's claims "were written under a lot of stress, and they described the situation as worse it was", and that a new team is taking over, with the service being resumed in 2 weeks.
At the same time, the CrofAI twitter account was also supposedly "taken over" by the team, starting each twitter reply with "Hey, Nathan here", stating the founder is stepping back and a "team" is taking over everything. This fake pretense act only lasted a few hours, and scared either by the public not buying the Nth fake story of the pathological liar that CrofAI is, or by the public's replies reminding him that what he committed is numerous counts of wire fraud, he has now deleted all his online presence: nahcrof.com and crof.ai return 404, Twitter page is deleted, /r/CrofAI sub is now private.
Here is another image of the owner admitting that he was defrauding customers for the entire 2 year operation of his service, then begging the investigator to help him cover his tracks and not expose him
EDIT: Commenters pointed out that NahCrof is 4chan in reverse. The owner's Discord name was "Devious Flimflam". Flimlam is defined as "deception, fraud". Looks like it was a deliberate scam operation from the get-go, and the owner's age was among the many lies.
I cannot stress this enough: if you bought any credits (even if you used them up) you are entitled to a full refund for every transaction as the victim of fraud. Open a chargeback with your bank for every transaction made. If you used their API, assume that everything was logged and is currently being mined for personal information and API keys to sell on the black markets. Rotate your keys, change passwords, get a new debit/credit card.
submitted by /u/SorosAhaverom
[link] [comments] -
-
π crosspoint-reader/crosspoint-reader 1.6.5rc release
Summary
Library view
Recent Books has grown into a powerful way to browse your entire collection on your SD card. Sort by recently added, title, or author, and use search to instantly find exactly what you're looking for.
X4 Classic support
The new ESP32-S3-based X4 Classic is officially supported now.
The rest
List navigation is a bit snappier. SD reads are a bit faster. Sleep-screen transparency is more accurate. KOSync now sends more precise EPUB reading positions. EPUB lists, hidden content, chapter position display, and end-of- book navigation also received fixes. The release also reduces font and EPUB memory pressure, fixes USB drive disconnection, and improves web file-transfer safety.
What's Changed
- chore: update pioarduino to 55.03.311 by @serialx in #3397
- fix: Fixes KOSync memory checks and reduces memory pressure by @itsthisjustin in #3412
- fix: pack font manifest catalog into one arena by @fain182 in #3398
- docs(issue forms): Correct links to scope/roadmap by @cassidyjames in #3433
- fix(reader): synchronize end-of-book menu selection by @Daviex in #3418
- fix: render NFD Hangul filenames from macOS transfers by @serialx in #3036
- fix: reader's menu book chapter current position by @unnamedd in #3437
- fix: stabilize X3 EPUB anti-aliasing by @uxjulia in #3439
- fix(input): wake the idle poll on raw button contact so short presses register by @Techneaux in #3463
- feat: HTTP serve static with Cache-Control and ETag headers by @shirok1 in #2560
- chore: add direct download links for PR artifacts by @Uri-Tauber in #3389
- fix(webserver): normalize every user-supplied path and escape file names in the files page by @s0lness in #3353
- chore: Consolidates grayscale capability checks and enables absolute grayscale for supported screens by @itsthisjustin in #3478
- fix: don't display elements with hidden HTML attribute by @jjharpham in #3390
- fix(KOSync): compare mapped KOReader sync positions by @WhoTheHeck in #3111
- fix: update OTA to recognize the new format by @Uri-Tauber in #3493
- fix(debugging_monitor): if PSRAM is logged, add subplot by @olifre in #3490
- fix(KOSync): preserve precise KOSync upload progress positions by @WhoTheHeck in #3174
- refactor: reduce EPUB heap fragmentation with unique ownership by @serialx in #3518
- fix: reduce font-cache heap fragmentation by @serialx in #3521
- fix: release font caches before EPUB chapter layout by @serialx in #3527
- chore: add x4 Classic to CI pipelines by @Uri-Tauber in #3532
- docs: make roadmap easier to scan by @fain182 in #3517
- fix: number ordered lists and fix list container indents by @jan-xyz in #3500
- fix: dropped presses while a list repaints by @Techneaux in #3534
- perf: batch SdFat's SPI transfers on ESP32 by @osakanataro in #3501
- fix: USB OTG not disconnected when you unplug the cable by @itsthisjustin in #3538
- feat: Library view by @oreglio in #3366
- fix: Skip bw rendering on sleep images & fix white as transparent for sleep covers by @itsthisjustin in #3541
New Contributors
- @cassidyjames made their first contribution in #3433
- @Daviex made their first contribution in #3418
- @unnamedd made their first contribution in #3437
- @Techneaux made their first contribution in #3463
- @shirok1 made their first contribution in #2560
- @s0lness made their first contribution in #3353
- @jjharpham made their first contribution in #3390
- @olifre made their first contribution in #3490
- @osakanataro made their first contribution in #3501
Full Changelog :
1.6.0...1.6.5rc -
π anthropics/claude-code v2.1.272 release
What's changed
- Bug fixes and reliability improvements
-
π Servo Blog Your Donations at Work: One Year of Sponsored Servo Development rss
Last September, the Servo project announced that long-time maintainer Josh Bowman-Matthews (@jdm) would work part-time on improving the Servo contributor experience, entirely funded by the monthly donations on OpenCollective and GitHub. In his own words, here is a look back over the past year!
First of all, I am enormously grateful to everyone who financially supports Servo, as those donations have enabled me to devote significant time to a project that I care a lot about. Some highlights from that funded work that Iβm proud of:
- I nominated 8 newmaintainers
- I reviewed 1150 pull requests
- I filed 114 issues targeted at newer contributors (92% of them have been fixed)
- I wrote new documentation about borrow hazards, experimental features, the AI policy, finding things to do, and fixing stable and intermittent test failures
On top of that, I spent time diagnosing unexpected failures in othersβ PRs and fixed numerous intermittent test failures that made merging PRs more difficult for everyone.
A few pieces of work from this period that stand out to me:
- supporting a large scale rewrite of Servoβs JS engine integration to address intermittent panics related to garbage collectionβI reviewed lots of pull requests, but also filed many issues that enabled the work addressing the panics to be spread across many other contributors
- getting tagged in to help understand test failures, uncovering our broken window.open behaviour, and eventually making a lot of flaky tests more stable
- supporting another contributorβs grant proposal to work on Servo that was approved!
This role Iβve carved out means a lot to meβIβve found a healthy balance that allows me to spend time with my family as well as make meaningful contributions to Servo, and I get to spend a lot of time looking for ways to make the project more accessible for others. A big thank you to everybody supporting the project and my work; each individual monthly donation makes a big difference! Iβm excited to see whatβs possible in the coming year.
-
- September 14, 2026
-
π anthropics/claude-code v2.1.271 release
What's changed
- Added fast mode in Claude Code Remote sessions (cloud and self-hosted runners): the host's fast-mode setting or
/fasttyped in the session applies where your organization allows it - Added mouse support to the
/configpanel in fullscreen mode: the wheel scrolls the settings list, a click on a setting's value changes it, and the row under the pointer is highlighted - Added
claude self-hosted-runner --drain-marker-file <path>: when that file exists at a SIGTERM drain, the runner reports its exit to the server as a host drain (telemetry only) - Added per-command
allowed_domainsto Bash, PowerShell and Monitor in auto mode with sandboxing: the hosts a command needs are reviewed with it and opened for it alone; other hosts are refused - Added
omitClaudeMdto agent frontmatter and--agentsJSON, letting custom and plugin subagents run without user, project and local CLAUDE.md files; managed policy files still load - Added
--accept-command <sha256>toclaude plugin installandclaude plugin updateto accept exactly the command a previous--jsonrun displayed, instead of-y - Added support for a
multiplierabove 1, up to 10, in themodelPricingmanaged setting and the Claude apps gatewaypricingblock, for marked-up internal chargeback rates - Added a spinner tip pointing Bedrock, Vertex AI, Foundry and LLM gateway users to the Claude desktop app; the claude.ai desktop app tip now suggests
/desktop, which offers to download the app - Fixed a cached organization policy being reused after switching accounts, organizations, or API keys, and the policy not refreshing until the hourly check when the credential changes mid-session
- Fixed the tool and command lists not updating when the organization policy finishes loading after startup or changes mid-session
- Fixed an enterprise
managed-mcp.jsonthat can't be read or parsed being ignored: it now keeps exclusive MCP control (user, project and plugin servers don't load) and warns at startup - Fixed org policy being fetched through, and rejected by, third-party local proxies set via
ANTHROPIC_UNIX_SOCKET; they are again treated like other custom gateways, including for Remote Control - Fixed cloud sessions rejecting every subagent tool call ("updatedInput β¦ failed schema validation") when a workflow or agent approval was applied after the session's worker restarted
- Fixed
/fast offanswering "Fast mode unavailable" instead of turning fast mode off when the organization has fast mode disabled - Fixed sessions started with
CLAUDE_CODE_SKIP_FAST_MODE_ORG_CHECKre-sending fast requests every turn after the API rejected fast mode; the rejection now stands and its reason is shown - Fixed fast mode under
CLAUDE_CODE_RETRY_WATCHDOGfailing the turn on a usage-credits limit, or retrying an overload at fast speed, instead of falling back to standard speed - Fixed Bash permission checks missing the file that
fmt,columnand similar commands read when it follows an option the checker doesn't recognize - Fixed Bash permission checks skipping files a wildcard expands to when the wildcard sits in a command's pattern or option value (for example
grep -v dir/* file) - Fixed Bash permission checks so that shell variable declaration flags cannot misrepresent the command being run
- Fixed Bash commands with two directory changes, a subshell, or a
cd+gitchain skipping the prompt underpermissions.blockReadsOutsideWorkingDirectoriesin bypass and auto mode - Fixed a stale
.git/config.lockbreakinggit checkout -b,git push -uandgit configfor the rest of a session after a sandboxed command failed to start (Linux) - Fixed settings file changes made outside the session going unnoticed on macOS machines whose system file-event service is saturated; the watcher now falls back to polling
- Fixed resumed
claude -psessions whose tools all come from MCP servers failing with "At least one tool must have defer_loading=false" - Fixed turns failing with "API returned an empty or malformed response" when an LLM gateway returns the non-streaming reply as
text/plain - Fixed sustained high CPU usage and repeated tool-list requests when an MCP server sends
list_changednotifications in a tight loop - Fixed MCP OAuth mishandling client registrations: denying consent forced a new one, one for another redirect URI was reused, and a concurrent write could delete a valid one or keep a mismatched one
- Fixed tool search returning no match when Claude selects an MCP tool by its bare name instead of its full
mcp__server__toolname - Fixed Ctrl+O cancelling pending MCP server reconnects, and
/mcpsent from Remote Control failing while the transcript view is open - Fixed the Claude in Chrome prompt telling the model to load tools through ToolSearch when ToolSearch is unavailable
- Fixed cross-session messages held by the receiving session's permission-mode policy leaving no trace: headless senders now get a delivery notice, and
SendMessageresults no longer imply it was read - Fixed Claude starting a second copy of a background command (such as a watch task or dev server) that was still running after the conversation was compacted
- Fixed
/modelwarning about losing the conversation cache when switching back to the model the conversation actually ran on - Fixed
/reload-skillsreporting a skill count that disagreed with the slash menu after/cd - Fixed
/resumeand/continueshowing only 1-2 sessions in fullscreen mode on short terminals - Fixed
/resumeand/teleportkeeping the previous conversation's file-read tracking, so Claude could edit files the resumed conversation had never read - Fixed
--resumedropping the 1M context window ([1m]) when the resumed session's model family differs from the configured default model - Fixed artifacts attached with
/artifactsdisappearing from the session after--resume - Fixed background sessions (
claude --bg,claude agents) not watching the artifacts they publish for republishes made elsewhere - Fixed custom agents, slash commands and output styles beyond the first not loading from a virtual drive that reports inode 0, such as an encrypted vault mounted as a Windows drive
- Fixed self-hosted runner sessions silently losing all host config (settings, skills, plugins, MCP servers) when the host config directory exceeds 64 MiB; added
--host-config-snapshot disk|memory - Fixed skills synced from claude.ai staying on disk indefinitely after signing out; copies not refreshed within
cleanupPeriodDaysnow move to the recoverable trash at the next launch - Fixed spinner tips suggesting commands that aren't available for your account type or are disabled in your session
- Fixed the
/add-dirpath input: the left and right arrow keys now move the cursor, and Enter adds only the typed path instead of also adding the highlighted completion - Fixed text fields outside the main prompt moving a leading
!to the end of what you typed (!foocame out asfoo!) - Fixed the interactive
/hooksmenu crashing when a hook matcher is named after an inherited object property such as__proto__orconstructor - Fixed a fullscreen rendering glitch where text kept a stale background color after the box around it lost its background
- Fixed Delete in st and Alt+arrow keys in rxvt-unicode not working in attached background sessions
- Fixed the terminal's replies to capability queries (
^[[?1;2c) appearing at the shell prompt or in an editor when Claude Code exits, is suspended, or opens an editor right after starting - Improved terminal rendering performance: large diffs and long transcripts render faster, with fewer slow frames
- Improved startup time slightly by skipping a redundant validation of built-in model data on every launch
- Improved hook feedback: while a SessionStart, UserPromptSubmit, PreToolUse or SessionEnd hook runs, the spinner says so with elapsed time, and Esc cancels a prompt waiting on a SessionStart hook
- Improved the spinner status during long thinking: it now reads "deep in thought" after 45s, and shows "picking the thought back up" while recovering from the output-token limit
- Improved dynamic workflows to pause when you hit your usage limit and continue automatically when it resets, instead of dropping the affected agents
- Improved Remote Control to leave fewer empty sessions on claude.ai when setup fails on a flaky network
- Improved the Claude in Chrome message in cloud sessions when the browser can't be reached: it now says the computer may be asleep before it suggests an install
- Improved
claude mcp serve: a running tool call now sends a progress update every 30 seconds, so clients show it is still running and idle timeouts don't abort a long command that prints nothing - Improved Foundry and Claude Platform on AWS sessions: an
alwaysLoadMCP server that finishes connecting mid-conversation is usable on the next turn without a tool-search round trip - Improved Markdown files published as artifacts: they now render as styled document pages (title header, document typography, syntax-highlighted code)
- Improved Artifact tool publish errors: a publish with no file now says to write the page to a file first, and an unsupported file type is reported before a missing favicon
- Improved the Artifact tool's error when a page declares a capability its contract version lacks: it now lists every supported capability and notes when a newer contract version has it
- Improved artifact watching: a session can now watch up to 10 published artifacts at once for republishes made elsewhere, up from 5
- Improved PDF @-mentions to say "page count unknown" instead of a page count guessed from the file size when pdfinfo cannot count the pages
- Improved
/mobileto show a single QR code for claude.ai/mobile, which opens the right app store for your phone - Changed auto mode so that a skill's or slash command's inline
!shell commands follow default-mode permission rules instead of the classifier; a command no rule decides runs as a reviewed tool call - Changed auto mode so a subagent reports back to its caller through a dedicated hand-back call that the safety classifier reviews, instead of its last message being reviewed after the fact
- Changed Monitor watches to always have a deadline (at most 30 minutes; 10 in single-prompt
-pruns) and notify Claude to re-arm, replacing the no-timeoutpersistentoption - Changed the IDE selection indicator in the prompt to a
[β§ β¦]pill that wraps with the text instead of squeezing multi-line prompts; delete it with Backspace to leave the selection out - Changed the default dynamic workflow size to small on Pro plans and lowered the medium size guideline from 15 to 10 agents
- Changed Claude apps gateway, Bedrock, Vertex AI, and Foundry sessions so that they no longer refresh a leftover claude.ai login that the session does not use
- Updated the bundled
claude-apiskill to enableeager_input_streamingon streaming custom tools, and to start deliverable-shaped Managed Agents work withuser.define_outcome - [VSCode] Added an Attach Open File setting that, when turned off, stops the open file from being added to messages; selected text is still attached
- [VSCode] Fixed the Hooks and Permission rules dialogs reporting a save that landed as failed, and the Hooks dialog going blank under a plugin-only policy lock or showing color codes in save errors
- [VSCode] Fixed Hooks dialog saves: no duplicate hook on replace, a header name retyped in other capitals keeps its secret, and settings.local.json is gitignored before the save returns
- [VSCode] Fixed session history showing only the current session when the workspace is on a Windows mapped network drive or SUBST drive
- [VSCode] Fixed the session list's Active filter hiding open idle sessions when Open is also checked in the filter menu
- [VSCode] Fixed a new chat switching back to the previous chat when the session list refreshed
- [VSCode] Fixed open tabs and the side bar keeping the old config folder until a window reload after
CLAUDE_CONFIG_DIRchanged in theenvironmentVariablessetting - [VSCode] Fixed console windows flashing on Windows when the extension runs background commands such as git, ripgrep, and the sign-in status check
- [VSCode] Fixed the prompt cache clock's hover text appearing only after a delay, and the auto-compact icon showing the browser's own tooltip beside its popup
- [VSCode] Improved the Hooks dialog: a save refused because of the settings file itself now opens a popup with an "Open settings file" button and the reason behind "Copy error"
- [VSCode] Changed the on state of toggle switches from Claude orange to the editor theme's button color
- [Claude Code on the web] Fixed a cloud session sometimes taking about ten minutes to respond after its process exited while the session still looked live; sending a message now restarts it right away
- [Claude Code on the web] Changed the Routines page on claude.ai/code to a new layout with Yours and Templates tabs and two-column routine cards that show run status, and removed its calendar view
- [Claude Code on the web] Added a Custom network access option to the Cloud environments editor in admin settings, with the same allowed-domains list the environment dialog on claude.ai/code offers
- [Claude Code on the web] Improved the Cloud environments admin page: it shows the default environment for Claude Tag and Claude Code, with a link to change it, and marks the recommended kind to create
- [Claude Tag] Fixed Claude in a channel where it stays active losing its working context about once an hour when the conversation is mostly in threads; thread activity now keeps it from being reset
- [Claude Tag] Fixed a thread that asked Claude to watch a pull request no longer hearing about CI failures, comments and reviews after Claude was restarted in that thread
- [Claude Tag] Fixed deleting the first message of a thread Claude had already replied in not ending Claude's work there; it now stops, as it did when a message with no replies was deleted
- [Claude Tag] Fixed Claude holding back a post because of an earlier instruction addressed to a different bot or assistant; only instructions addressed to Claude bind it, and it asks when unsure
- [Claude Tag] Fixed the reply-mode card Claude posts on joining a busy channel saying it "sees a lot of automated posts" when the channel is only chatty or large; the card now names the real reason
- [Claude Tag] Improved the Environment picker in Claude Tag admin settings: options are labeled Anthropic-hosted or self-hosted, with links to edit that environment or create one
- [Code Review] Fixed a pull request in a repository reviewed once per PR sometimes getting no review when a commit arrived while its review was waiting to start; it now reviews the requested commit
- [Code Review] Fixed Code Review occasionally posting the same findings two or three times when GitHub reported an error for a review it had in fact created
- [Code Review] Fixed follow-up reviews re-posting a security finding a person had already resolved when a later push moved the lines it was anchored to
- [Code Review] Fixed reopening a finished /ultrareview cloud session in the Claude app starting the whole review over again unprompted
- Windows: Fixed PowerShell commands failing with "Exit code 1" and no output when the session's temp output path reaches 260 characters
- Added fast mode in Claude Code Remote sessions (cloud and self-hosted runners): the host's fast-mode setting or
-
π uswds/uswds USWDS 3.14.0 release
What's new in USWDS 3.14.0
Features
Package | A11y | Breaking | Markup change | Description
---|---|---|---|---
usa-accordion,uswds-core| Yes | Yes | Yes | Added a left-aligned expand/collapse icon option. A new$theme-accordion-icon-positionsetting (default:"start") lets teams set icon placement globally. The.usa-accordion--icon-startand.usa-accordion--icon-endmodifier classes support per-instance placement. This improves discoverability for users viewing content at high magnification or zoom levels. Thanks @HopeTurnerUSCIS, @rosamundtgov, and @jeana-adhoc! (#6789)βοΈ Teams should verify layout at common zoom levels for the new default accordion behavior.
usa-breadcrumb| Yes | Yes | - | Breadcrumbs now wrap by default. The previous truncation behavior is now opt-in via the newusa-breadcrumb--truncatemodifier class. Thanks @AKnassa! (#6722)βοΈ Teams should confirm breadcrumbs display as expected and add
usa- breadcrumb--truncateif they want the old truncation behavior.
usa-range| Yes | - | Yes | Added a visible hint to the range slider. A newusa-hintelement with the text "Move the slider to change the value" is added above the slider so sighted users receive the same guidance that screen reader users already had. Thanks @ravitejapioneerblaze-code! (#6673, #6811)βοΈ Teams should pull in the updated markup.
usa-range| Yes | - | - | Improved range slider border visibility. The border is now 2px and uses thebase-darkertheme token. A focus ring is also added to the slider input. Thanks @manichandra! (#6659)
usa-date-picker| Yes | - | Yes | Addedaria-current="date"to today's date button. Assistive technologies can now programmatically identify the current date in the calendar widget. Thanks @daresTheDevil! (#6593)
usa-file-input| - | - | - | Error border now uses theerror-darktoken. The file input error state previously usedsecondary-dark, which could show the wrong color in projects with distinct secondary and error palettes. Thanks @manichandra! (#6669)Bug fixes
Package | A11y | Breaking | Markup change | Description
---|---|---|---|---
usa-modal| Yes | - | - | Closing a modal now always restores screen reader access to the page. If the element that opened the modal had left the document by the time the modal closed, page content keptaria-hidden="true"and stayed invisible to assistive technology until reload. Thanks @vssinghh! (#6786)
usa-modal,uswds-core| Yes | - | Yes | Fixed modal content being read twice by screen readers. The default focus target has changed β on open, focus now moves to the first enabled button in the modal footer, or the first enabled button in the modal if no footer button is present.FocusTrapno longer usesautoFocus. (#6703)βοΈ Teams should verify modal focus lands where expected after this update.
usa-memorable-date| Yes | - | Yes | Added per-field hints to the memorable date component. The component previously used a single shared hint referenced by all three fields viaaria-describedby, causing screen readers to repeat the full instruction block on every field focus. Each field now has its own targeted hint. The visible group hint remains for sighted users witharia-hidden="true". (#6725)βοΈ Teams should update to the new per-field hint markup. Teams supporting other languages should update their hint strings.
usa-file-input| Yes | Yes | Yes | Removed the drag instruction on mobile and coarse-pointer devices. The file input previously showed "Drag file here or choose from folder" on all devices, including mobile where drag-and-drop isn't a practical interaction. Coarse-pointer devices now show and announce "Choose from folder" only. Thanks @manichandra! (#6660)βοΈ Teams should check for layout changes and update any accessibility tests that assert the old exact instruction text.
usa-character-count| Yes | - | - | Deferredaria-liveto prevent iOS VoiceOver from announcing character count on page load. Live updates continue to fire normally during typing. Thanks @daresTheDevil! (#6595)
usa-character-count| - | - | - | Fixed the label selector so it correctly finds the associated label. Thanks @ealexhaywood! (#6385)
usa-footer| - | Yes | - | Restricteddata-tagto heading elements. The footer's big link list was vulnerable to XSS through unsanitizeddata-tagvalues. Non-heading elements now gracefully fall back toh4. Thanks @IHIutch! (#6674)βοΈ Teams should review any footer
data-tagvalues that aren't heading elements.
usa-banner,uswds-core| - | - | - | Fixed toggle so it resolvesaria-controlsfrom the component's root node. This allows banner toggles to work correctly when used inside a shadow root. Thanks @arpitjain099! (#6714)
uswds-core| - | - | - | Fixed the language selector Escape key handler. Thanks @arpitjain099! (#6713)
uswds-core| - | - | - | Guarded the keymap against non-keyboard events from datalist selections. This prevents a console error when a user selects an option from a datalist. Thanks @vijaygovindaraja! (#6594)
usa-table| - | - | - | Restored the row header border in borderless tables. Row-scoped body header cells now keep their top border so row headers don't appear visually disconnected. Thanks @manichandra! (#6661)
usa-table| - | - | - | Fixed.usa-sr-onlytable caption causing heading-row border collapse. Thanks @IHIutch! (#6633)
usa-time-picker| - | - | - | Added missing combobox style dependency to the time picker package. Thanks @IHIutch! (#6634)
usa-input,usa-textarea,usa-range,usa-combo-box,usa-input-prefix-suffix,usa-select| - | - | - | Setbox-sizing: border-boxon the%block-input-stylesmixin to prevent overflow. Components in host environments that reset global box sizing no longer overflow their containers. Thanks @VenkateshAddala! (#6736)βοΈ Teams should verify these elements display correctly in projects with custom global
box-sizingresets (e.g. those who set$theme-global-border- box-sizing: false).
usa-in-page-navigation| - | - | - | Standardized the component's enhancement guard to usedata-enhancedin line with other USWDS components. (#6688)
uswds-core| - | - | - | Fixed ink assignment referencing the wrong variable. Custom ink colors in a project's theme were referencing the wrong system token. Thanks @nektro! (#6651)βοΈ Teams should verify that custom ink colors in their theme render as expected.
Guidance changes
Alert
The alert component page now recommends that alert headings start with the alert type to improve clarity and urgency of the message, both for accessibility and general usability, as well as adding extended guidance to help teams use the correct alert type. Thanks @jeana-adhoc and @rosamundtgov! (#3288)
Markup changes
Memorable date
The memorable date component's three fields now each have their own
aria- describedbyhint instead of sharing a single
group hint. Teams who've copied the memorable date markup should update to the per-field pattern:<fieldset class="usa-fieldset"> <legend class="usa-legend">Date of Birth</legend> - <span class="usa-hint" id="mdHint">For example: January 19 2000</span> + <span class="usa-hint" aria-hidden="true" id="memorable-date-hint"> + Select a month. Enter 1 or 2 digits for the day and 4 digits for the year. + </span> <div class="usa-memorable-date"> <div class="usa-form-group usa-form-group--month usa-form-group--select"> <label class="usa-label" for="date_of_birth_month">Month</label> - <select class="usa-select" id="date_of_birth_month" name="date_of_birth_month" aria-describedby="mdHint"> + <span class="usa-hint usa-sr-only" id="memorable-date-month-hint">Select a month from the dropdown.</span> + <select class="usa-select" id="memorable-date-month" name="memorable-date-month" aria-describedby="memorable-date-month-hint"> ... </select> </div> <div class="usa-form-group usa-form-group--day"> <label class="usa-label" for="date_of_birth_day">Day</label> - <input class="usa-input" aria-describedby="mdHint" id="date_of_birth_day" name="date_of_birth_day" ... /> + <span class="usa-hint usa-sr-only" id="memorable-date-day-hint">Enter 1 or 2 digits for the day.</span> + <input class="usa-input" aria-describedby="memorable-date-day-hint" id="memorable-date-day" name="memorable-date-day" ... /> </div> <div class="usa-form-group usa-form-group--year"> <label class="usa-label" for="date_of_birth_year">Year</label> - <input class="usa-input" aria-describedby="mdHint" id="date_of_birth_year" name="date_of_birth_year" ... /> + <span class="usa-hint usa-sr-only" id="memorable-date-year-hint">Enter 4 digits for the year.</span> + <input class="usa-input" aria-describedby="memorable-date-year-hint" id="memorable-date-year" name="memorable-date-year" ... /> </div> </div> </fieldset>File input
The file input no longer renders the drag instruction on coarse-pointer or mobile devices. On those devices, the
instruction now reads "Choose from folder" instead of "Drag file here or choose from folder". For fine-pointer devices,
the text remains "Drag file here or choose from folder." Teams with tests that assert the exact instruction text should
update those tests.- Drag file here or choose from folder + Choose from folderAccordion icon alignment
The default alignment for the accordion toggle icon switches to the left for better accessibility for users who zoom or
use screen magnification. Teams can now use theusa-accordion--icon-startorusa-accordion--icon-endmodifier to
left-align or right-align the expand/collapse icon at the instance-level respectively. Icon position can be set globally
with the$theme-accordion-icon-positionSass setting. The default behavior ("start"/ left-aligned) is changed from
v3.13.0, and the historical behavior can be preserved with$theme-accordion- icon-position: "end".- <div class="usa-accordion"> + <div class="usa-accordion usa-accordion--icon-start">or
- <div class="usa-accordion"> + <div class="usa-accordion usa-accordion--icon-end">Or set globally in your theme:
+ $theme-accordion-icon-position: "start";or
+ $theme-accordion-icon-position: "end";Dependencies and security
Dependency updates
Dependency name | Previous version | New version
---|---|---
lit | 3.2.1 | 3.3.3
receptor | 1.0.0 | --Note:
receptorhas been removed as a dependency. Its functionality has been reimplemented in first-party code.
Thanks @aduth! (#6489)Dev dependency updates
Dependency name | Previous version | New version
---|---|---
@babel/core | 7.26.8 | 7.29.7
@babel/preset-env | 7.26.8 | 7.29.7
@chanzuckerberg/axe-storybook-testing | 6.3.1 | --
@material-design-icons/svg | 0.14.13 | 0.14.15
@rollup/plugin-commonjs | 28.0.3 | 29.0.3
@spiriit/vite-plugin-svg-spritemap | 4.0.0 | 6.0.0
@storybook/addon-a11y | 6.5.16 | 9.1.20
@storybook/addon-essentials | 6.5.16 | --
@storybook/addon-links | 6.5.16 | --
@storybook/builder-webpack5 | 6.5.16 | --
@storybook/html | 6.5.16 | --
@storybook/html-vite | -- | 9.1.20
@storybook/manager-webpack5 | 6.5.16 | --
@storybook/test-runner | -- | 0.23.0
@types/node | 20.14.10 | 24.13.3
@uswds/compile | -- | 1.3.2
autoprefixer | 10.4.20 | 10.5.0
axe-core | 4.10.2 | --
axe-playwright | -- | 2.2.2
concurrently | -- | 10.0.3
css-loader | 6.8.1 | --
del | 6.0.0 | 8.0.1
esbuild | -- | 0.28.1
eslint | 8.56.0 | 10.8.0
eslint-config-airbnb-base | 15.0.0 | --
eslint-config-prettier | 9.1.0 | 10.1.8
eslint-plugin-airbnb-base | 0.0.1-security | --
eslint-plugin-import | 2.31.0 | --
eslint-plugin-import-x | -- | 4.17.1
eslint-plugin-lit | 2.0.0 | 2.3.1
eslint-plugin-no-unsanitized | 4.1.2 | --
file-loader | 6.2.0 | --
globals | -- | 17.8.0
gulp | 4.0.2 | 5.0.1
gulp-mocha | 9.0.0 | 10.0.1
gulp-postcss | 9.0.1 | 10.0.0
gulp-rename | 2.0.0 | 2.1.0
gulp-sass | 6.0.0 | 6.0.1
html-webpack-plugin | 5.6.3 | 5.6.8
http-server | -- | 14.1.1
magic-string | -- | 0.30.21
merge-stream | 2.0.0 | --
mocha | 10.8.2 | 11.8.0
postcss | 8.5.2 | 8.5.25
postcss-discard-comments | 6.0.2 | 8.0.2
postcss-import | 15.1.0 | --
postcss-loader | 7.3.3 | --
postcss-preset-env | 9.6.0 | --
prettier | 3.4.2 | 3.9.6
react-dom | 17.0.2 | --
resolve-url-loader | 5.0.0 | --
sass-embedded | 1.83.4 | 1.100.0
sass-loader | 16.0.4 | --
sass-true | 6.0.1 | 10.1.0
sinon | 12.0.1 | 22.1.0
snyk | 1.1295.3 | 1.1306.2
storybook | -- | 9.1.20
style-loader | 3.3.3 | --
svgo | 3.3.2 | 4.0.2
twig | -- | 3.0.0
twigjs-loader | 1.0.3 | --
vite | 6.2.2 | 6.4.3
vite-plugin-svg-sprite | 0.6.2 | --
wait-on | -- | 9.1.0
webpack | 5.98.0 | 5.109.2
webpack-cli | 5.1.4 | 7.2.20 vulnerabilities in regular dependencies (dependencies for USWDS projects installed with
npm install @uswds/uswds)19 vulnerabilities (11 moderate, 3 high) in devDependencies (development dependencies)
SHA-256 for release
da91c65e6fc736fa397f0daf6ca2c2c95711506d85c7ad2537a4570725401e1cAdditional contributions
- Thanks to @szepeviktor for fixing typos and EditorConfig improvements. (#6720, #6278)
- Thanks to @manichandra for fixing 18F guide links. (#6658)
- Thanks to @ericsorenson for upgrading our eslint (#6690) and Storybook (#6697, #6715) tooling
- Thanks to @olsonap for fixing initialization on the interactive components in our Storybook instance (#6664)
- Finally, thanks to @annepetersen, @chandracarney, @ethangardner, and @jonathanbobel for working on this release, along with other employees across Technology Transformation Services (TTS) at General Services Administration (GSA).
-
π exe.dev Executing Commands With exe.dev's HTTPS API rss
exe.dev has one API, which looks like a CLI, but it can be used over multiple transports. You can run commands over SSH or send those same commands over HTTPS to
https://exe.dev/exec. This extends to running commands on your VMs!# Generate a token using your SSH key. (You can do this on the web UI as well!) TOKEN=$(ssh exe.dev ssh-key generate-api-key --exp 1h --cmds=ssh,new --label tmp-$(date +%s) --json | jq .token -r) # Create a new VM curl https://exe.dev/exec -H "Authorization: Bearer $TOKEN" \ -d 'new --name example-vm' {"vm_name":"example-vm"... # Run "hostname" on that new VM curl https://exe.dev/exec -H "Authorization: Bearer $TOKEN" \ -d 'ssh example-vm hostname' example-vmSee the complete docs: https://exe.dev/docs/https-api-run-on-vm
This API shape composes nicely with the powerful primitives in your VM. So, if you want to start a task and return immediately, you can do something like the following with
setsid nohupand output redirection.curl https://exe.dev/exec -H "Authorization: Bearer $TOKEN" \ -d "ssh example-vm 'setsid nohup sleep 10 > /tmp/out 2>&1 &'" # Returns immediately -
π r/LocalLLaMA Nvidia's RTX 5090 vanishes from online retail in the US β third-party sellers now demand as much as $9,500 for Nvidia's fastest GPU rss
| submitted by /u/Norwood_Reaper_
[link] [comments]
---|--- -
π benji.dog rss
After talking about it for a bit, and meeting some great people at HTML day, I decided to finally try to start up a Homebrew Website Club in the Twin Cities.
The first meeting will be on Monday Sep 21, 2026 at 5:00PM at Loons Coffee.
Link to the event: https://events.indieweb.org/R2UxWLeu3IHZ
-
π r/LocalLLaMA For the GPU poor. K2 Horizon 7B ranks between qwen 3.6 27B and qwen 3.6 35BA3b on the Artificial Analysis Intelligence Index. rss
| From initial testing it seems pretty solid so far. Asked it to compile the latest llama.cpp for CUDA and its doing well so far. If this thing holds up to its score then its SHOCKINGLY good for its size. https://huggingface.co/IFM/K2-Horizon-7B-GGUF submitted by /u/Uncle___Marty
[link] [comments]
---|--- -
π r/LocalLLaMA UkisAI Swift-Qwen3.8-27B / -58.3% thinking, x1.95 speed while keeping the accuracy of xhigh rss
| Hi everybody, we post-trained Qwen 3.8 27B to be more efficient by figuring out which tokens were linked to overthinking and penalizing them without "attacking" the reasoning length directly then fixed the accuracy with a bit of secret sauce (hint On-Policy Distillation) and achieved great results (-58% thinking tokens, 1.95x speed up, <1% accuracy loss) so we wanted to open-source it and hear the feedback of the community. This is the link to the model: https://huggingface.co/ukisai/Swift-Qwen3.8-27b We also also providing a Free Research Purpose API (OpenAI compatible), courtesy of Nvidia who were kind enough to provide us with the GPUs. You can use it to try out the model if you do not have enough compute to run it, it's limited at 5RPM. https://ukisai.com/api/swift/v1/models We also made a GGUF (Q1-Q8) and there's also a few nice community (Bartowski) quants with even lower/higher precision. The community also created amazing NVFP4, W4A16 and Uncensored versions of the model you can find on Huggingface. IMPORTANT: Our training approach is not a replacement for the reasoning effort settings, chat templates or token caps but is complementary and targets a completely separate issue (overthinking and "anxiety-like" reasoning loops prior seen in PTQ, but as far as we identified also prominent in BF16 of this size class LLMs as well). Contrary to popular belief, these specific patterns do not contribute to answer quality when properly targeted. (our thesis being: reasoning length IS extremely important and should NOT be shortened by force, but rather optimized). This is also demonstrated bellow in our xhigh vs medium effort benchmark table. The goal is to keep xhigh accuracy while reducing only the unnecessary part of thinking. I will TLDR you on our thought process, research, training and benchmarks.- When running our quantized Qwen 3.8 27B instances we were very annoyed by random reasoning loops (in the paper bellow refered to as "overthinking errors". These random loops were persistent throughout medium and low reasoning settings.
- We remembered a paper by Meta that's supposed to target this phenomenon in PTQ, but when used straight out of the box got mixed results.
- We figured to try if it's a matter of the targeting the right keywords and tuning the parameters, so we used our 8xH100 box and and generated a large amount of different (ofc out of distribution) domain (coding, language, vision, agentic) traces.
- We then grouped the ones with overthinking and found "common denominator" tokens between them and targeted the most prominent ones.
- We then built an inference-time penalizer of those tokens as seen in the paper with the hopes of simply generating traces and doing cross-entropy SFT over them.
- Did not work at all, but the penalizer seemed to work much better than the tokens provided in the paper and not only for lower precision models but for bf16 as well. Hence we kept experimenting with it. We built a loss function using the tokens we identified and ran LoRa SFT over the traces prev generated and reasoning seemed to be falling off significantly but the accuracy seemed to follow. The reasoning reduction seemed to be generalizing.
- After a significant amount of tinkering (literally since the day of Qwen 3.8 27B release) we were satisfied with the reasoning reduction. After that we searched for ways of restoring the accuracy. We experimented with several methods, including RL(GSPO), On-Policy Distillation and using the ThinkingCap 3.6 27B adapter chunks until we were satisfied with our accuracy loss. We managed to restore it to <1% loss on almost all of our OOD in house tests
- We then performed intensive intensive benchmarks, across several reasoning efforts, precision variants etc. We ran into a few problems, one of which is that to get a reliable score we needed to run each benchmark 10x (5x on base + 5x with our adapter, this being the standard procedure on the Qwen 3.6 27B model card on Terminal Bench which we followed). After running it, the performance converged to 40-60% token reduction with <1% accuracy loss across GPQA, MMLU, Terminal Bench 2.1, LiveCodeBench v6, ERQA, C-Eval, IFBench, HMMT25, with an exception being AIME26 with an accuracy loss of 4.6%, which we later linked to a bug during training with a specific token relevant for math-related reasoning being penalized and are planning to fix it in an updated release.
The benchmarks: (raw benchmark files here - https://github.com/UkisAI/Swift-Qwen3.8-27B-evals/ ) Swift-27B vs Qwen3.8-27B (BF16, all benchmarks ran x5, thinking effort xhigh) | Benchmark | Qwen3.8-27B | Swift-27B | Median tokens
---|---|---|---
GPQA-Diamond | 88.4% | 88.3% | 58% fewer
LiveCodeBench v6 | 76.8% | 81.6% (+4.8pp, due to default truncation in LCB it is not performance gain) | 46% fewer thinking tokens
Terminal-Bench 2.1 | 66.7% | 65.8% | 39% fewer
MMLU-Pro | 85.5% | 85.0% | 28% fewer
C-Eval | 90.0% | 90.6% | 19% fewer
IFBench | 73.5% | 71.8% | 51% fewer
AIME 2026 | 98.7% | 94.0% | 50% fewer
HMMT (Nov 2025) | 99.3% | 96.0% | 46% fewer
ERQA (vision) | 67.5% | 66.3% | 55% fewerToken savings hold at every reasoning effort (mean thinking reduction): xhigh 41%, medium 23%, low 26% (albeit with accuracy loses of 1-4% on medium and 1-2% on low which we need further testing for)
Swift at xhigh vs the base's own effort settings on GPQA-Diamond (198 questions x 5 seeds):
Model / effort | Accuracy | Median tokens
---|---|---
Base xhigh | 88.4% | 6,642
Swift xhigh | 88.3% | 2,771
Base medium | 84.1% | 1,753So Swift keeps xhigh accuracy at under half the tokens, and beats base-medium by 4pp at roughly 1.6x its tokens.
End note:
While we are keen on complete open-source, we still need to keep a part of our training and data private, being a new lab. The license is not Apache 2.0, but it only affects companies >$1M. We hope this does not pose a problem for the community, but we are open to feedback on it.
We want to contribute as much as possible to the community and would really appreciate feedback on our work, quantization or Swift model requests. For context, we are working on Swift 3.8 Flash Next right now and have so far gotten up to -30% thinking token usage while maintaining xhigh accuracy, which we take as a strong indicator our methodology is reproducible across the Qwen model family. Will explore other families as soon as we have the capacity and would love to see which ones the community would love for us to optimize first.
submitted by /u/Secure_Recording_472
[link] [comments] -
π osolmaz/pi-workflows v0.17.3 release
This patch removes one upgrade trap. A workflow server process answers with the package
version it loaded at start. After an upgrade, a client from the new version refused that
server, and no command could reach it. The mismatch message then asked for packages that
already matched.Recorded server stop
pi-workflows server stopandpi-workflows server startnow read
server/server.lock.jsonwhen the handshake reports a version mismatch. The command checks
the recorded process start identity, stops that process withSIGTERM, and uses a bounded
SIGKILLafter a five-second grace.server stopreports the stopped process and its process ID.server startstops the
recorded server and then starts a matching one, so one command returns the machine to a
working state.server statusreports the mismatch and changes nothing.The extension keeps its report-only behavior, because two Pi installations of different
versions can share one state directory. The mismatch message names that recovery step.Install
pi install npm:@osolmaz/pi-workflowsThe
piwviewer ships as a crate:cargo install pi-workflows --version 0.17.3State
This release does not change the durable schema. State written by
0.17.2stays valid. -
π osolmaz/pi-workflows v0.17.2 release
This release sends only the current workflow state to Pi. It also renames the engine's
components to one vocabulary, so durable state written by 0.17.1 needs a reset.Current workflow state
Pi receives one bounded view of the active run. Node identity, kind, state, and attempt
count arrive as facts. Free-form text is cut at 4 KiB on a character boundary, and a JSON
detail above 8 KiB is left out of the frame. Complete values stay reachable through a
content reference, so no client receives an unbounded array or a truncated value.The engine selects one current message per session. It prefers the open turn's message,
then the oldest eligible pending message, then the newest sent message that needs Pi work,
then a cancelled step message, then a retained terminal message. Message selection reads
metadata only, and the complete history stays available through a page call.Progress facts travel with the view. The view carries one newest record per key, the
monitor schedule, and the monitor estimate.Component names
The engine, the extension, the server, the viewers, the documentation, and the tests now
use one vocabulary. The current names are workflow server, workflow runner, resource
manager, resource runner, and managed resource. The earlier names are gone from every file
a reader can open, and a test keeps them out. Ordinary network language and third-party
package names stay as they are.Node identity limit
A workflow definition accepts a node ID of at most 4096 bytes. A cut identity names no
node, so the engine rejects the definition instead. An identity that fills the limit still
travels in full within one client frame.Performance
The session message revision now comes from one indexed counter row with triggers, so
selection does not scan the session. On a 50,000-message session that read fell from
5.4 ms to 9.8 Β΅s, and a repeated session view on a warm cache costs 245 Β΅s instead of
28.4 ms. The held selection follows the view cache bound of 64 entries and keeps its
retained-terminal result.Fixes
The queue names the active run when a start call meets a taken session reservation, so the
caller no longer sees a raw database error. The test harness stops the workflow servers its
run started; each leftover server held about 80 MB for the life of the machine.State reset
This release changes the durable schema in place. On first start, Pi Workflows reports
Pi Workflows durable state is incompatible. Back up and move state.sqlite with its -wal and -shm files, then start Pi Workflows to create a new state.sqlite database.Move or
delete that database and let the new build create it. This is the alpha policy: no
migration and no compatibility path.Known gap
The general post-workflow turn and the missing-submission reminders still need runtime
restoration. The recorded recovery path covers the work that the extension can still
deliver today.Install
pi install npm:@osolmaz/pi-workflowsThe
piwviewer ships as a crate:cargo install pi-workflows --version 0.17.2 -
π r/LocalLLaMA RTX PRO 5500 Blackwell (84GB) released rss
| submitted by /u/TechNerd10191
[link] [comments]
---|--- -
π r/LocalLLaMA Right to Intelligence. Protect your right to run local AI. rss
| With all the recent drama surrounding AI safety. Itβs obvious that open source could be caught in the crossfire. submitted by /u/Euphoric_Ad9500
[link] [comments]
---|--- -
π r/LocalLLaMA DeepSeek V4.1 Flash beats Astra on AA's new benchmark rss
| https://artificialanalysis.ai/articles/artificial-analysis-intelligence-index-v4-3 AA shipped a new benchmark last week as part of the Intelligence Index v4.3 update β a brand-new private eval that replaces ΟΒ³. Astra was farming a ton of points on it and used those to get even with Fable, butβ¦ looks like we have a new king. So they changed the index twice in three days to make Astra look not-quite-worse than Fable, and then a random guy quietly took first place on it. submitted by /u/Randomdotmath
[link] [comments]
---|--- -
π WerWolv/ImHex Nightly Builds release
Nightly
033a248Changelog- impr: Link patterns when opened instead of importing them into Project
- git: Update sponsorship message, remove PayPal link
- fix: Stop the background services before the cleanup (#2898)
- feat: Escape pattern values for display (#2892)
- feat: Add support for enum
in-variables (#2890) - patterns: Update pattern language
- build: Upgrade AppImage to use GCC 16
-
π Armin Ronacher Interpreting Pangram rss
Yesterday David Sacks wrote a tweet and within a few minutes people did, what they usually do, and they asked Pangram if it was AI. And Pangram said it's entirely AI generated. To which David replied that these AI detectors are bogus.
Now Pangram has a pretty low false positive rate, but if you have ever used an LLM as a writing assitant, you will have probably noticed that it claims your posts 100% AI, even though you don't feel like they are.
Pangram itself is a trained model, that attempts to detect segments of text as being definitely human, definitely AI and a mixture of the two. If you want to know how it works, they published a paper. The short summary is that they are manufacturing its own training data by starting from collections of known human authored text. An LLM is then tasked to understand the text and write a fresh new text on the same topic. They also let the LLM perform partial edits on that original human text and through that they can pick up on these co-authored details. Pangram claims their model to have rates of 0.0041% false AI accusations and 0.34% missed AI text.
So now that we know this I figured it might be fun to have an LLM re-create David's tweet. I first came up with a prompt. And when I say I came up with that prompt I in fact used an LLM to propose to me from that tweet what I might want to say for the structure. I'm sure if you ask Pangram about if the above text is AI, it will probably say so, but that's not really the point. The point is that I then used Opus 5 to generate a text which reads entirely AI generated.
If you are curious, this is the prompt I used:
Original prompt to generate a David Sacks like tweet
Please write an 8 paragraph tweet about "Pacing the Frontier", not longer than 350 words.
Context of this tweet is this post by Dario: https://darioamodei.com/post/we-must-pace-the-frontier
And this tweet by Sam Altman: "I agree with Dario that we need to pace the frontier. This has been a primary topic of discussions we've had at OpenAI in recent weeks.
Committing to having independent evaluators with employee-like access is a great idea, and we will do the same. We'll have more to share soon."
Structure for the post:
- Open with a concession: Note that Dario ("We Must Pace the Frontier") and Sam Altman both want to slow down at the frontier. Say "go ahead" which reads as a surprising response.
- Establish they own the frontier: Argue OpenAI and Anthropic hold a duopoly on frontier intelligence by all kind of metrics (market share, capability, revenue etc.) and that they themselves claim the lead is widening via RSI.
- Concede you can't see their unreleased models, so if those are scary, being responsible is their call.
- Follow with a list of a rapid-fire paragraph ("stop pretending") rejecting the asks from Dario's post.
- Name the commercial self-interest (Slowing down isn't purely altruistic)
- Close with the challenge that pacing buys room for a smarter regulatory debate than Bernie Sanders "shut it all down". Say something about China and Open Weight models.
The text that Opus 5 then wrote, was this one:
Dario published "We Must Pace the Frontier." Sam agreed, and said OpenAI will also commit to independent evaluators with employee-like access. My response is not the one they expect: go ahead. Please do.
Because you two are the frontier. OpenAI and Anthropic hold a duopoly on frontier intelligence by every metric anyone actually uses: capability, revenue, enterprise share, developer mindshare. And you both keep telling us the lead is widening, that models are starting to improve models. If that's true, pacing costs you a quarter you can reclaim whenever you like.
I also can't see your unreleased checkpoints. If what's sitting behind the curtain genuinely scares the people who trained it, then slowing down is your call to make, and the right one. I'm not going to second-guess a risk assessment I have no access to.
But stop pretending the rest of us are the problem. Stop pretending this is a collective action failure in which a handful of startups are the defectors.
Stop pretending open weights are the dangerous frontier while the two of you ship the most capable model in the world every few months. Stop pretending third-party evals require new law, when you both just committed to them voluntarily, in public, on a blog.
And stop pretending it's purely altruism. Pacing the frontier is also margin repair. It slows the price war, stabilizes the capex story, stretches depreciation schedules across a longer product cycle, and makes life considerably harder for fast followers who survive by distilling whatever you shipped last month. Safety and self-interest are pointing the same direction here. That's worth saying out loud.
Still, the upside is real. Pacing buys room for a smarter regulatory debate than the one on offer, where the loudest alternative is Bernie Sanders' "shut it all down." That's a slogan, not policy. Meanwhile China keeps shipping competitive open weights, and any rule that binds two American labs while the rest of the world downloads its capability for free isn't safety, it's theater with a very expensive ticket price.
And well, Pangram agrees that this is 100% AI. So far, so uninteresting. It does read somewhat like David's tweet, but obviously not entirely. Given that the original prompt does not have enough information to re-create the tweet entirely you would expect some divergences.
The actual thing that interests me is if you can take this output at all, and then rewrite it from scratch, but by sticking to the general structure and ideas. Will Pangram give us a AI or human rating?
I read the generated text. Then I read each paragraph and decided to rewrite and rephrase it without an LLM. According to some similarity checkers, they the final texts are 50% similar which seems about right. But strictly speaking, not a single sentence is the same. Here is the 100% human rewritten text of the above one. No LLM was used to write it, but an LLM was used to fix up typos in the end. That from my experience really does nothing to tick off an LLM detector.
Dario has written "We Must Pace the Frontier," and Sam from OpenAI has agreed. My response might surprise people: go ahead, please.
You two are the frontier! Your companies, OpenAI and Anthropic, are at the frontier by all metrics: revenue, developer mindshare, adoption, capabilities. And yet you both claim that your lead is widening as a result of recursive self-improvement as models are improving models. You currently are the duopoly of self-improving models!
I am unable to see what unreleased models you have. When what you have behind those doors really scares your folks, then you should slow down. I'm not going to tell you otherwise and I support you.
But please don't pretend we are the problem. Stop pretending you need our permission. Stop pretending this is all a collective issue when in reality this is all on you. Stop pretending open weights are the problem here. Stop pretending pulling third-party evaluators in requires lawmaker involvement. And for the love of all the good things in the world: stop pretending this is all about altruism.
Pacing the frontier is also about your margins, and it makes it harder for fast followers. And it patches up your capex story and has the potential for slowing down the price war ahead of the IPOs.
But yes: pacing might give us the space for a better debate than Bernie Sanders' "shut it all down." There is no policy there. And while we're having fights at home, China will keep shipping competitive open-weight models and won't adhere to any American agreements.
This is all regulatory capture hiding behind a safety debate, and the rest of the world is watching.
So what does it say? Well this text too comes back as 100% slop. And it does not surprise me all that much. I have generally noticed that if you rely on an LLM to give your text structure, it will score badly on Pangram even if you do plenty of edits over it. In fact, it's quite unlikely you're going to get a post that starts out as slop into a structure that will make it appear that it's not.
I came to quite appreciate the existance of Pangram because at the very least it has made me quite aware of some of the effects that using LLMs for writing blog posts has. This blog has been AI supported for about two years (as you can see from the AI transparency link on the bottom but I did notice that I became both more reliant on those tools and that they have become much more aggressive editors and it gave me pause.
Yet, I also think that plenty of people will find a "100% AI" rating misleading when in fact the author has done plenty of editing. But maybe it's fair to have this to show up as entirely AI?
-