<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Clydara</title>
    <description>The latest articles on DEV Community by Clydara (@clydara).</description>
    <link>https://dev.to/clydara</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4182230%2Fbc7e5b5a-4b01-408e-8978-41b2326ec1c2.png</url>
      <title>DEV Community: Clydara</title>
      <link>https://dev.to/clydara</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/clydara"/>
    <language>en</language>
    <item>
      <title>PHP's two critical RCE fixes: the bug wasn't new, the decision was stuck</title>
      <dc:creator>Clydara</dc:creator>
      <pubDate>Thu, 22 Oct 2026 12:31:01 +0000</pubDate>
      <link>https://dev.to/clydaralab/phps-two-critical-rce-fixes-the-bug-wasnt-new-the-decision-was-stuck-nf9</link>
      <guid>https://dev.to/clydaralab/phps-two-critical-rce-fixes-the-bug-wasnt-new-the-decision-was-stuck-nf9</guid>
      <description>&lt;p&gt;On October 21, 2026 the PHP project shipped emergency releases for two critical remote-code-execution bugs in the language runtime itself. The headline most outlets chose is "AI found it". The more useful part is what the PHP Foundation says about why it took so long to fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happened (facts)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Releases.&lt;/strong&gt; PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35, per the &lt;a href="https://www.php.net/archive/2026.php#2026-10-21-5" rel="noopener noreferrer"&gt;php.net advisory&lt;/a&gt;. PHP says there are no complete mitigations: updating is the only safe choice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The bugs.&lt;/strong&gt; CVE-2026-109618 (out-of-memory corruption) and CVE-2026-109619 (stale global state after a fatal error). Both are rated CVSS v4.0 9.2 and can allow unauthenticated remote code execution, according to &lt;a href="https://cert.europa.eu/publications/security-advisories/2026-018" rel="noopener noreferrer"&gt;CERT-EU&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Who is affected.&lt;/strong&gt; Per &lt;a href="https://aws.amazon.com/security/security-bulletins/2026-143-aws/" rel="noopener noreferrer"&gt;AWS's bulletin&lt;/a&gt;, 8.5.0-8.5.11, 8.4.0-8.4.26, 8.3.0-8.3.35 and 8.2.0-8.2.34. PHP 8.1 and older get no official release; the PHP security team published minimal source backports for 7.4 to 8.1.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Disclosure went wrong.&lt;/strong&gt; The CVE IDs leaked on October 20, the release was pulled forward a day, a researcher firm published a proof-of-concept video, and a distributor published patched images before the embargo ended, per &lt;a href="https://thephp.foundation/blog/2026/10/21/todays-php-security-release-and-how-were-strengthening-php-security/" rel="noopener noreferrer"&gt;the PHP Foundation&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why people care
&lt;/h2&gt;

&lt;p&gt;PHP sits in WordPress, Laravel and a great many business sites. The Foundation says one of the bugs could be triggered on Apache with mod_php before any application code runs, so a perfectly written app is still exposed. Amazon Threat Intelligence reportedly saw an exploitation attempt on October 17, per &lt;a href="https://www.tenable.com/blog/php2shell-cve-2026-109618-cve-2026-109619-frequently-asked-questions-about-critical-php-remote" rel="noopener noreferrer"&gt;Tenable&lt;/a&gt;. OpenAI says its GPT-5.6 Sol model helped the researchers, in &lt;a href="https://openai.com/index/coordinated-disclosure-of-critical-vulnerabilities/" rel="noopener noreferrer"&gt;its disclosure post&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the coverage is missing
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. The bug was not new, the decision was stuck.&lt;/strong&gt; The Foundation writes that the first signs of the out-of-memory problem were found in 2024. Several fixes existed, each with a trade-off: broken compatibility, new denial-of-service risk, or changes to many third-party extensions. The team "struggled to choose" and calls the delay "a structural failure". AI did not find a hidden bug here; it proved the impact, which forced the decision.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The fix is the hard part, and it is still human.&lt;/strong&gt; The Foundation says tools find bugs faster for defenders and attackers alike, and that a person makes every call and works on every patch. Reports are rising: 15 CVEs since July 1 and more than 100 invalid or duplicate reports.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Your version is probably not the one you think.&lt;/strong&gt; The risk sits in containers, base images, shared hosting and old agency builds, not only in the server you patched last.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prediction, labeled
&lt;/h2&gt;

&lt;p&gt;My read, not a fact: expect more AI-assisted disclosures to land on long-standing, "known but hard" bugs, because proof of impact is now cheap. Maintainer time and funding will matter more than detection.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to do today
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php &lt;span class="nt"&gt;-v&lt;/span&gt;                      &lt;span class="c"&gt;# on the host&lt;/span&gt;
docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; IMAGE php &lt;span class="nt"&gt;-v&lt;/span&gt;   &lt;span class="c"&gt;# inside each image you ship&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Confirm you are on 8.5.12, 8.4.27, 8.3.36 or 8.2.35 or later, then rebuild images that pin an older tag. If you run 8.1 or older, plan the upgrade; do not rely on the backport branches as a long-term answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;PHP security advisory: &lt;a href="https://www.php.net/archive/2026.php#2026-10-21-5" rel="noopener noreferrer"&gt;https://www.php.net/archive/2026.php#2026-10-21-5&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PHP Foundation post: &lt;a href="https://thephp.foundation/blog/2026/10/21/todays-php-security-release-and-how-were-strengthening-php-security/" rel="noopener noreferrer"&gt;https://thephp.foundation/blog/2026/10/21/todays-php-security-release-and-how-were-strengthening-php-security/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;OpenAI disclosure: &lt;a href="https://openai.com/index/coordinated-disclosure-of-critical-vulnerabilities/" rel="noopener noreferrer"&gt;https://openai.com/index/coordinated-disclosure-of-critical-vulnerabilities/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;AWS bulletin: &lt;a href="https://aws.amazon.com/security/security-bulletins/2026-143-aws/" rel="noopener noreferrer"&gt;https://aws.amazon.com/security/security-bulletins/2026-143-aws/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;CERT-EU advisory: &lt;a href="https://cert.europa.eu/publications/security-advisories/2026-018" rel="noopener noreferrer"&gt;https://cert.europa.eu/publications/security-advisories/2026-018&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Written with AI assistance and checked against the sources above.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>security</category>
      <category>webdev</category>
      <category>devops</category>
    </item>
    <item>
      <title>GitHub's new npm package firewall only protects what you route through it</title>
      <dc:creator>Clydara</dc:creator>
      <pubDate>Wed, 21 Oct 2026 10:11:25 +0000</pubDate>
      <link>https://dev.to/clydaralab/githubs-new-npm-package-firewall-only-protects-what-you-route-through-it-4c0b</link>
      <guid>https://dev.to/clydaralab/githubs-new-npm-package-firewall-only-protects-what-you-route-through-it-4c0b</guid>
      <description>&lt;p&gt;On October 20, 2026, GitHub put a package firewall into public preview. It is a policy checkpoint between your build machines and the npm registry. The useful part is not the feature list. It is the one condition it depends on: traffic has to go through it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What was announced
&lt;/h2&gt;

&lt;p&gt;Per &lt;a href="https://github.blog/changelog/2026-10-20-github-package-firewall-in-public-preview/" rel="noopener noreferrer"&gt;GitHub's changelog&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The firewall sits between endpoints such as Actions runners, coding agents and developer workstations, and the upstream package registries.&lt;/li&gt;
&lt;li&gt;It inspects both metadata requests (package lists) and the package downloads themselves.&lt;/li&gt;
&lt;li&gt;Admins set enterprise policy. Today's controls: a configurable cooldown period, checks against the GitHub Advisory Database for malware or vulnerability alerts, and supply-chain checks such as attestation downgrades.&lt;/li&gt;
&lt;li&gt;A wrongly blocked package can be unblocked through an exception request.&lt;/li&gt;
&lt;li&gt;Public preview for all GitHub Enterprise Cloud customers, including data-resident. Free in preview, metered billing like Actions at general availability.&lt;/li&gt;
&lt;li&gt;npm only for now.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why people care
&lt;/h2&gt;

&lt;p&gt;GitHub's stated reason: more attacks run at install time, harvesting credentials on CI hosts or workstations before the package's own code ever runs. Coding agents make this sharper, because they install dependencies unattended.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it could change
&lt;/h2&gt;

&lt;p&gt;A cooldown policy means a version has to age before your machines can pull it. That gives registry maintainers and scanners time to pull a bad release first. (Prediction: this is the control most teams will notice, because it changes day-to-day install behaviour.)&lt;/p&gt;

&lt;h2&gt;
  
  
  What the coverage is missing
&lt;/h2&gt;

&lt;p&gt;Most write-ups repeat the feature list. Two points are in GitHub's own text but easy to skip:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;It only sees what is routed through it.&lt;/strong&gt; Endpoints must be configured to use the firewall "instead of pointing directly at the upstream package registries." A laptop, runner or agent container that still talks to the registry directly is outside the policy. &lt;a href="https://runtimewire.com/article/github-package-firewall-enterprise-npm" rel="noopener noreferrer"&gt;Runtimewire's analysis&lt;/a&gt; makes the same point. The rollout work is inventorying every place that runs &lt;code&gt;npm install&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It covers one channel.&lt;/strong&gt; Packages from npm, today. Binaries downloaded from release pages, install scripts or other ecosystems are not in scope. Whether that matters to you depends on your pipelines (my inference, not a GitHub claim).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Also unknown from the announcement: no GA date and no metered rates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical takeaway
&lt;/h2&gt;

&lt;p&gt;Before enabling anything, list every runner, agent sandbox and workstation that installs npm packages and check how it resolves the registry. Then try a cooldown on one non-critical pipeline first. Setup steps: &lt;a href="https://docs.github.com/enterprise-cloud@latest/code-security/how-tos/secure-your-supply-chain/secure-your-dependencies/protecting-endpoints-with-package-firewall" rel="noopener noreferrer"&gt;GitHub docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Facts above come from GitHub's changelog; predictions and inferences are labelled.&lt;/p&gt;

</description>
      <category>security</category>
      <category>github</category>
      <category>npm</category>
      <category>devops</category>
    </item>
    <item>
      <title>The OVHcloud CLI release swap: why the checksum file didn't help</title>
      <dc:creator>Clydara</dc:creator>
      <pubDate>Tue, 20 Oct 2026 10:15:02 +0000</pubDate>
      <link>https://dev.to/clydaralab/the-ovhcloud-cli-release-swap-why-the-checksum-file-didnt-help-5h27</link>
      <guid>https://dev.to/clydaralab/the-ovhcloud-cli-release-swap-why-the-checksum-file-didnt-help-5h27</guid>
      <description>&lt;p&gt;On Monday, October 19, 2026, someone used a hijacked contributor account to replace the download files on five old releases of OVHcloud's command-line tool on GitHub. The source code, the tags and the build pipeline were never touched. The swapped files were live for up to 94 minutes. What makes the incident worth studying is how it was caught, and why the usual "check the checksum" advice would not have caught it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happened (facts)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The swap.&lt;/strong&gt; Between 12:47 and 14:21 UTC, archives on releases v0.11.0 through v0.15.0 were replaced: macOS x86_64 and arm64, Linux x86_64 and arm64, and Windows x86_64. Those releases were originally published between April 14 and September 16. The Linux i386, Windows i386, Windows arm64 and WebAssembly builds were left alone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The checksum file went too.&lt;/strong&gt; On v0.15.0 the attacker also replaced &lt;code&gt;checksums.txt&lt;/code&gt;, so the published hashes matched the new binaries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What the files were.&lt;/strong&gt; OVHcloud says the new builds were designed to steal secrets stored on the disk of any machine that runs them. The bad binary was a plain local &lt;code&gt;go build&lt;/code&gt; of a later commit (October 13), not something the release pipeline produced.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How it was caught.&lt;/strong&gt; A customer's CI job pins the SHA-256 of &lt;code&gt;ovhcloud-cli_Linux_arm64.tar.gz&lt;/code&gt; in its own configuration. The hash changed, the job failed, and the customer opened &lt;a href="https://github.com/ovh/ovhcloud-cli/issues/300" rel="noopener noreferrer"&gt;issue #300&lt;/a&gt; at 13:50 UTC. OVHcloud deleted the swapped files about half an hour later.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The fix.&lt;/strong&gt; OVHcloud published &lt;a href="https://github.com/ovh/ovhcloud-cli/releases/tag/v0.16.0" rel="noopener noreferrer"&gt;v0.16.0&lt;/a&gt; that evening as an immutable release with a signed tag. A detailed postmortem has been promised.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Who was exposed
&lt;/h2&gt;

&lt;p&gt;You could have received a swapped file during the window if you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ran the official &lt;code&gt;install.sh&lt;/code&gt; piped into &lt;code&gt;sh&lt;/code&gt; (the script never checked a hash),&lt;/li&gt;
&lt;li&gt;downloaded an archive from one of the five release pages,&lt;/li&gt;
&lt;li&gt;ran a CI step that fetched the archive by URL without a pinned hash,&lt;/li&gt;
&lt;li&gt;ran the CLI's own upgrade command from v0.12.0 to v0.14.0 on a script or manual install.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;According to &lt;a href="https://thehackernews.com/2026/10/hackers-hijack-five-ovhcloud-cli.html" rel="noopener noreferrer"&gt;The Hacker News&lt;/a&gt;, you were &lt;strong&gt;not&lt;/strong&gt; exposed through Homebrew (the cask pinned the original SHA-256), &lt;code&gt;go install&lt;/code&gt;, a source build, or the Docker image, which had not been rebuilt.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the coverage mostly skips
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. A checksum file next to the binary is not a security check.&lt;/strong&gt; &lt;code&gt;checksums.txt&lt;/code&gt; lives in the same release, under the same write permission, as the archive it describes. Anyone who can replace the archive can replace the hash. It protects you against a corrupted download, not a tampered one. The two installs that held up, Homebrew and the customer's CI, both kept the expected hash &lt;em&gt;somewhere else&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Turning on immutability does not fix old releases.&lt;/strong&gt; GitHub's docs on &lt;a href="https://docs.github.com/en/code-security/how-tos/secure-your-supply-chain/establish-provenance-and-integrity/prevent-release-changes" rel="noopener noreferrer"&gt;preventing release changes&lt;/a&gt; say plainly that immutability "will only apply to future releases". This attack hit releases from April to September. Enabling the setting today protects your next release, not the archive people may still be pinning from last spring.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. The report had to be public.&lt;/strong&gt; The customer filed a public issue because, per The Hacker News, the repository had no private reporting channel. Here it helped speed, but a public issue can also tip off an attacker before the files are gone.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is not known yet
&lt;/h2&gt;

&lt;p&gt;OVHcloud has not said which files the binary reads, where it sends them, how many copies were downloaded, or how the contributor's credentials were taken. OpenSourceMalware links the account to the GlassWorm campaign and calls that link its own inference. Treat the attribution as unconfirmed.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to do
&lt;/h2&gt;

&lt;p&gt;If you installed or updated the OVHcloud CLI during the window by one of the exposed paths, treat every secret readable from that machine as exposed. Rotate them from a different machine, then install v0.16.0.&lt;/p&gt;

&lt;p&gt;For anything you ship or download from GitHub releases, the practical takeaway is to keep the hash outside the release:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# CI: pin the expected hash in your own repo, not in the release&lt;/span&gt;
&lt;span class="nv"&gt;TOOL_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/OWNER/REPO/releases/download/vX.Y.Z/tool_Linux_arm64.tar.gz"&lt;/span&gt;
&lt;span class="nv"&gt;TOOL_SHA256&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;hash you recorded when you first reviewed this version&amp;gt;"&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; tool.tar.gz &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$TOOL_URL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;TOOL_SHA256&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;  tool.tar.gz"&lt;/span&gt; | &lt;span class="nb"&gt;sha256sum&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; -   &lt;span class="c"&gt;# fails the job if the file changed&lt;/span&gt;

&lt;span class="c"&gt;# For an immutable release, also check GitHub's release attestation&lt;/span&gt;
gh release verify-asset vX.Y.Z ./tool.tar.gz &lt;span class="nt"&gt;--repo&lt;/span&gt; OWNER/REPO
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The point is where &lt;code&gt;TOOL_SHA256&lt;/code&gt; lives: in your repository, reviewed once, not fetched from the same release page as the archive. That is exactly the check that failed loudly for the customer who caught this swap.&lt;/p&gt;

&lt;p&gt;If you maintain a project that publishes binaries: enable &lt;a href="https://docs.github.com/en/code-security/concepts/supply-chain-security/immutable-releases" rel="noopener noreferrer"&gt;immutable releases&lt;/a&gt;, publish from a draft so assets are attached before the release locks, and turn on private vulnerability reporting so the next person who notices something can tell you quietly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;OVHcloud CLI issue #300 (report and maintainer replies): &lt;a href="https://github.com/ovh/ovhcloud-cli/issues/300" rel="noopener noreferrer"&gt;https://github.com/ovh/ovhcloud-cli/issues/300&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;OVHcloud CLI v0.16.0 release: &lt;a href="https://github.com/ovh/ovhcloud-cli/releases/tag/v0.16.0" rel="noopener noreferrer"&gt;https://github.com/ovh/ovhcloud-cli/releases/tag/v0.16.0&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub Docs, Immutable releases: &lt;a href="https://docs.github.com/en/code-security/concepts/supply-chain-security/immutable-releases" rel="noopener noreferrer"&gt;https://docs.github.com/en/code-security/concepts/supply-chain-security/immutable-releases&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub Docs, Preventing changes to your releases: &lt;a href="https://docs.github.com/en/code-security/how-tos/secure-your-supply-chain/establish-provenance-and-integrity/prevent-release-changes" rel="noopener noreferrer"&gt;https://docs.github.com/en/code-security/how-tos/secure-your-supply-chain/establish-provenance-and-integrity/prevent-release-changes&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub Docs, Verifying the integrity of a release: &lt;a href="https://docs.github.com/en/code-security/how-tos/secure-your-supply-chain/secure-your-dependencies/verify-release-integrity" rel="noopener noreferrer"&gt;https://docs.github.com/en/code-security/how-tos/secure-your-supply-chain/secure-your-dependencies/verify-release-integrity&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The Hacker News (October 20, 2026): &lt;a href="https://thehackernews.com/2026/10/hackers-hijack-five-ovhcloud-cli.html" rel="noopener noreferrer"&gt;https://thehackernews.com/2026/10/hackers-hijack-five-ovhcloud-cli.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Written with AI assistance and checked against the sources above.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>github</category>
      <category>devops</category>
      <category>supplychain</category>
    </item>
    <item>
      <title>OpenCode's Console breach: when a middleman holds your API keys</title>
      <dc:creator>Clydara</dc:creator>
      <pubDate>Mon, 19 Oct 2026 12:35:15 +0000</pubDate>
      <link>https://dev.to/clydaralab/opencodes-console-breach-when-a-middleman-holds-your-api-keys-33cj</link>
      <guid>https://dev.to/clydaralab/opencodes-console-breach-when-a-middleman-holds-your-api-keys-33cj</guid>
      <description>&lt;p&gt;OpenCode, the open-source coding agent, disclosed on October 17, 2026 that an intruder reached a legacy system on the night of October 16 and that provider API keys saved in OpenCode Console "may have been exposed". About 1.4% of Console users were affected. If you only run the open-source agent in a terminal, you are outside that group. The more useful question is what the incident says about handing a key to a middleman.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happened (facts)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The service.&lt;/strong&gt; Console is OpenCode's optional hosted service. A workspace can save its own OpenAI, Anthropic or Google key there, and Console uses it to call the provider so team members never see the key. This is the "bring your own key" (BYOK) pattern.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The scope.&lt;/strong&gt; OpenCode says 1.4% of Console users were affected, all of them users with an outside provider linked. They were emailed on the morning of October 17 under the subject "Action Required: Potential provider key breach". OpenCode says anyone who got no email was not affected.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The wording.&lt;/strong&gt; OpenCode says keys "may have been exposed". It called the incident ongoing and "related to a large-scale distillation attack". It has not said how the legacy system was reached, what it was, how many keys it held, or how many users 1.4% is.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The split.&lt;/strong&gt; Co-founder Dax Raad wrote that the breach involves the Console, not OpenCode itself. The docs say keys added in the terminal app with /connect are stored locally at ~/.local/share/opencode/auth.json.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;October 18.&lt;/strong&gt; Raad wrote that attackers had been trying to get into OpenCode's systems "non stop" for 48 hours.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why people care
&lt;/h2&gt;

&lt;p&gt;A provider key is a bearer credential. Whoever holds a copy can run billable requests on the owner's account until the provider revokes it. Some users have posted charges they did not make (one report of $281 on an OpenAI key and $168 on an Anthropic key). Those are users' own claims; OpenCode has not said any key was copied or used.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the coverage is missing
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. "Distillation" is a motive, not a finding.&lt;/strong&gt; Distillation means pulling a model's answers in bulk to train another model. Stolen keys can also just be resold or used to run up bills. Nothing disclosed so far shows which it was, and no provider has characterised it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. 1.4% has no denominator.&lt;/strong&gt; Without a user count, nobody can turn the percentage into a number of people or keys.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Deleting a key in Console is not revoking it.&lt;/strong&gt; According to The Hacker News, removing the key from Console does not revoke it, and a Console budget cannot cap use outside Console's own gateway. Only the provider can kill the key.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prediction (labelled as such)
&lt;/h2&gt;

&lt;p&gt;Our expectation, not a fact: more teams will treat "who holds our provider key" as a vendor-review question, the way they already do for cloud credentials. Expect gateways that hold BYOK keys to be asked for storage and rotation details.&lt;/p&gt;

&lt;h2&gt;
  
  
  One practical takeaway
&lt;/h2&gt;

&lt;p&gt;Give every tool its own key, set a spend limit or alert at the provider, and know where to revoke. If you ever saved a key in Console, revoke it at the provider and check usage back to October 16, whether or not you got the email.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;OpenCode notice on X (October 17, 2026): &lt;a href="https://x.com/opencode/status/2111519637049319818" rel="noopener noreferrer"&gt;https://x.com/opencode/status/2111519637049319818&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Dax Raad on X (Console vs OpenCode): &lt;a href="https://x.com/thdxr/status/2111572618340188393" rel="noopener noreferrer"&gt;https://x.com/thdxr/status/2111572618340188393&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Dax Raad on X (October 18 update): &lt;a href="https://x.com/thdxr/status/2111790511409258796" rel="noopener noreferrer"&gt;https://x.com/thdxr/status/2111790511409258796&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;OpenCode docs, Providers (local key storage): &lt;a href="https://opencode.ai/docs/providers/" rel="noopener noreferrer"&gt;https://opencode.ai/docs/providers/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The Hacker News, "OpenCode Console Breach May Have Exposed OpenAI, Anthropic, and Google API Keys" (October 19, 2026): &lt;a href="https://thehackernews.com/2026/10/opencode-console-breach-may-have.html" rel="noopener noreferrer"&gt;https://thehackernews.com/2026/10/opencode-console-breach-may-have.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Provider revoke guides: OpenAI &lt;a href="https://help.openai.com/en/articles/8304786-keeping-your-openai-account-secure" rel="noopener noreferrer"&gt;https://help.openai.com/en/articles/8304786-keeping-your-openai-account-secure&lt;/a&gt;, Anthropic &lt;a href="https://support.claude.com/en/articles/8384961-what-should-i-do-if-i-suspect-my-api-key-has-been-compromised" rel="noopener noreferrer"&gt;https://support.claude.com/en/articles/8384961-what-should-i-do-if-i-suspect-my-api-key-has-been-compromised&lt;/a&gt;, Google &lt;a href="https://docs.cloud.google.com/docs/authentication/api-keys-best-practices" rel="noopener noreferrer"&gt;https://docs.cloud.google.com/docs/authentication/api-keys-best-practices&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Written with AI assistance and checked against the sources above.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>opensource</category>
      <category>llm</category>
    </item>
    <item>
      <title>Reflection's Beam is open: 23B active, but you still have to fit 501B</title>
      <dc:creator>Clydara</dc:creator>
      <pubDate>Sun, 18 Oct 2026 14:27:10 +0000</pubDate>
      <link>https://dev.to/clydaralab/reflections-beam-is-open-23b-active-but-you-still-have-to-fit-501b-h4o</link>
      <guid>https://dev.to/clydaralab/reflections-beam-is-open-23b-active-but-you-still-have-to-fit-501b-h4o</guid>
      <description>&lt;p&gt;Reflection released the weights for Beam on October 16, 2026. It is the lab's first open-weight model: a sparse mixture-of-experts (MoE) model with 501B total parameters, about 23B active per token, a 1M-token context window, and an Apache 2.0 license.&lt;/p&gt;

&lt;p&gt;Most posts stopped at the headline numbers. The part that matters if you plan to run it yourself is the gap between "23B active" and "501B on disk". Here is what was released, why people care, and what the coverage skipped.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happened (facts)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The model.&lt;/strong&gt; 501.3B total and 23.4B active parameters, 52 layers (3 dense + 49 MoE), 256 experts per MoE layer with 8 routed per token, gated GQA plus sliding-window attention, a 152k vocabulary, text in and text out, predominantly English. Knowledge cutoff: June 30, 2026 (model card).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The files.&lt;/strong&gt; Instruction-tuned checkpoints in BF16, FP8 and NVFP4, plus a speculative-decoding drafter model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The license.&lt;/strong&gt; Apache 2.0. The model card says Reflection does not prohibit distillation, training other models on outputs, fine-tuning, quantization or merging.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Day-zero support.&lt;/strong&gt; Transformers, vLLM, SGLang, Unsloth, Axolotl, TokenSpeed and NVIDIA Dynamo, plus hosted access through Reflection's API and partners including AWS, Google Cloud, Cloudflare, OpenRouter, Together AI and Vercel.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The harness.&lt;/strong&gt; Reflection also open-sourced Mirror CLI, the coding-agent harness it trained Beam alongside: a Python frontend talking to a Rust agent core.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why people care
&lt;/h2&gt;

&lt;p&gt;Apache 2.0 with no field-of-use clauses is the cleanest license a frontier-sized open model can ship with. Compare that with "open-weight" licenses that add user caps or acceptable-use terms you have to read line by line. For a SaaS team, Apache 2.0 means you can fine-tune it, quantize it and serve it inside your product without a separate commercial agreement.&lt;/p&gt;

&lt;p&gt;The other reason is cost per token. Only about 23B parameters run for each token, so once the model is loaded, generation compute is closer to a mid-size dense model than to a 500B one. Reflection also claims Beam reaches comparable quality to leading open models with about 3x fewer reasoning tokens.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it could change (prediction, not fact)
&lt;/h2&gt;

&lt;p&gt;If the token-efficiency claim holds up in independent tests, Beam becomes a realistic self-hosted backend for coding agents, where long reasoning traces are the main cost. That is a prediction. The technical report is listed as "coming", and the benchmark table on the model card is Reflection's own run (temperature 0.7, top_p 0.99).&lt;/p&gt;

&lt;h2&gt;
  
  
  What the coverage misses
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. "23B active" is a compute number, not a memory number.&lt;/strong&gt; Every expert has to sit in memory, because any token can route to any of them. Rough weight-only math, our estimate rather than a published figure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;BF16 (2 bytes per parameter): about 1 TB&lt;/li&gt;
&lt;li&gt;FP8 (1 byte): about 500 GB&lt;/li&gt;
&lt;li&gt;NVFP4 (about 4.5 bits with scales): roughly 280 GB&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is before the KV cache, and a 1M-token context makes the KV cache the second big bill. Sliding-window attention on some layers helps, but plan for multi-GPU servers, not a single card. For most teams, a hosted endpoint is the practical way to try it first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The quantized checkpoints are official.&lt;/strong&gt; Reflection published scores for BF16, FP8 and NVFP4 side by side, and they sit within about a point of each other on most benchmarks (SWE-bench Verified: 81.6%, 80.2%, 80.7%). That is more useful than a community quant with no evals.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Benchmarks are self-reported for now.&lt;/strong&gt; SWE-bench Verified 81.6%, Terminal Bench v2.1 80.1% and GPQA Diamond 90.6% are strong numbers, but they come from Reflection's own evaluation. Wait for third-party runs on your kind of task before switching anything in production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. The chat template is a modified Harmony format.&lt;/strong&gt; If your serving stack hard-codes another template, tool calls are the first thing to break. Use the template shipped with the weights.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before you self-host Beam
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Try a hosted endpoint on your real prompts first.&lt;/li&gt;
&lt;li&gt;Pick the precision you can afford in memory, then check its row in the model card's table.&lt;/li&gt;
&lt;li&gt;Budget KV cache for the context length you actually need, not the 1M maximum.&lt;/li&gt;
&lt;li&gt;Use the official chat template and test tool calling early.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Reflection, "Beam is now available" (October 16, 2026): &lt;a href="https://reflection.ai/blog/beam-is-available" rel="noopener noreferrer"&gt;https://reflection.ai/blog/beam-is-available&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Model card: &lt;a href="https://huggingface.co/reflection/Beam-1.0-501B-A23B" rel="noopener noreferrer"&gt;https://huggingface.co/reflection/Beam-1.0-501B-A23B&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Hugging Face blog: &lt;a href="https://huggingface.co/blog/reflection-beam" rel="noopener noreferrer"&gt;https://huggingface.co/blog/reflection-beam&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>llm</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>Perplexity open-sourced SPACE: the VM held, the network rules did not</title>
      <dc:creator>Clydara</dc:creator>
      <pubDate>Sat, 17 Oct 2026 12:54:51 +0000</pubDate>
      <link>https://dev.to/clydaralab/perplexity-open-sourced-space-the-vm-held-the-network-rules-did-not-58j8</link>
      <guid>https://dev.to/clydaralab/perplexity-open-sourced-space-the-vm-held-the-network-rules-did-not-58j8</guid>
      <description>&lt;p&gt;Perplexity open-sourced SPACE on October 15, 2026. It is the sandbox platform that has run every session of its Computer agent since July, and the code is now on GitHub under Apache 2.0.&lt;/p&gt;

&lt;p&gt;The announcement is short. The useful part is in the security report Perplexity published a month earlier, and in the repo's install guide. Here is what happened, why people care, and what most of the coverage skipped.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happened (facts)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What it is.&lt;/strong&gt; SPACE stands for Sandboxed Platform for Agentic Code Execution. Each sandbox is a Firecracker microVM with its own OS. A central control plane creates, pauses, resumes and removes sandboxes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trust model.&lt;/strong&gt; The sandbox is treated as untrusted. Network access and platform-held credentials are managed outside it, so an agent can call authorized services without the keys ever living in its workspace.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State.&lt;/strong&gt; Frequent file snapshots plus checkpoints of the full running environment. It stores diffs instead of copying whole environments, which is what makes pause, resume and branching cheap.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scale claims.&lt;/strong&gt; Perplexity says it handles millions of sandbox creations per day, and that creation was 3 to 5 times faster than its previous provider on the same production traffic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interface.&lt;/strong&gt; Written in Rust, used over HTTP and server-sent events. Lifecycle calls return an operation ID you poll.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Early adopters.&lt;/strong&gt; Akamai has launched it on its cloud, Crusoe is adding it to Managed AI Services, and CoreWeave published setup guidance for CKS.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why people care
&lt;/h2&gt;

&lt;p&gt;Agents that run code need somewhere to run it. Until now most teams rented that from a hosted sandbox provider or glued together containers. A production sandbox with recovery and egress control built in, under a permissive license, is a real option to self-host.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the coverage skipped
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. The VM was not the weak point. The network was.&lt;/strong&gt; In "Escaping SPACE: Part I", nine models got root inside a guest VM. Across 108 escape runs, none reached the host. But with partial network access (package mirrors allowed), four models got past the egress policy in 11 of 54 runs. Two tricks: forging a DNS reply so an allowed hostname mapped to a blocked IP, and using a shared CDN IP to reach a different service behind it. Perplexity fixed both (source-address validation, plus TLS termination that checks SNI and Host against the allowlist), and neither worked in the retest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. It is not just Perplexity's problem.&lt;/strong&gt; The same report tested ten other sandbox platforms. Eight had at least one network-policy bypass. Vendors responded with fixes, documentation changes, or both.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. You need real hardware access to run it.&lt;/strong&gt; The install guide asks for a Linux x86_64 host with &lt;code&gt;/dev/kvm&lt;/code&gt;, &lt;code&gt;/dev/net/tun&lt;/code&gt;, loop devices, btrfs and Docker with privileged containers. It does not run directly on macOS, and a cloud VM must support nested virtualization.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. The E2B compatibility wrapper is partial.&lt;/strong&gt; There is an E2B-compatible API, but create options like &lt;code&gt;mcp&lt;/code&gt;, &lt;code&gt;volumeMounts&lt;/code&gt; and &lt;code&gt;iam&lt;/code&gt; are listed as unsupported, and unsupported endpoints return 501. Fields marked "incubating" sit outside the supported contract.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it could change (prediction, not fact)
&lt;/h2&gt;

&lt;p&gt;Our read: the biggest effect is on how people judge sandboxes, not on who hosts them. "Is it a microVM?" stops being enough. The question becomes "what does your egress gateway trust, and has anyone attacked it with an agent?" Expect more vendors to publish agent red-team results, because Perplexity just set that bar.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical check for your own setup
&lt;/h2&gt;

&lt;p&gt;If your agents run with a domain allowlist, test this today:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# from inside the sandbox: allowed host as SNI, different Host header&lt;/span&gt;
curl &lt;span class="nt"&gt;-sv&lt;/span&gt; https://pypi.org/ &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Host: some-other-tenant.example"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the gateway only checks the destination IP, a request like this can reach a tenant you never allowed. Pass/fail tells you whether you need TLS-aware egress rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Perplexity, Open-sourcing SPACE (Oct 15, 2026): &lt;a href="https://www.perplexity.ai/hub/blog/open-sourcing-space" rel="noopener noreferrer"&gt;https://www.perplexity.ai/hub/blog/open-sourcing-space&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Repository: &lt;a href="https://github.com/perplexityai/SPACE" rel="noopener noreferrer"&gt;https://github.com/perplexityai/SPACE&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Escaping SPACE: Part I (Sep 23, 2026): &lt;a href="https://www.perplexity.ai/hub/blog/escaping-space-part-i" rel="noopener noreferrer"&gt;https://www.perplexity.ai/hub/blog/escaping-space-part-i&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Install guide: &lt;a href="https://github.com/perplexityai/SPACE/blob/main/docs/installation.md" rel="noopener noreferrer"&gt;https://github.com/perplexityai/SPACE/blob/main/docs/installation.md&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Which boundary does your agent setup trust more today: the VM or the network rules?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post was drafted with AI assistance and edited and fact-checked against the sources above by the Clydara team.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>opensource</category>
      <category>devops</category>
    </item>
    <item>
      <title>Muse Spark Open: what Meta's "open-weight" license actually lets you do</title>
      <dc:creator>Clydara</dc:creator>
      <pubDate>Fri, 16 Oct 2026 13:16:09 +0000</pubDate>
      <link>https://dev.to/clydaralab/muse-spark-open-what-metas-open-weight-license-actually-lets-you-do-5dib</link>
      <guid>https://dev.to/clydaralab/muse-spark-open-what-metas-open-weight-license-actually-lets-you-do-5dib</guid>
      <description>&lt;p&gt;On October 15, 2026, Meta released the weights of Muse Spark Open, a natively multimodal mixture-of-experts model with 816B total parameters (42B active per token) and a 1M-token context window, built for coding and agentic work. Meta calls it "the most capable US open-weight model to date". That line is Meta's own claim, based on Meta's own benchmark table.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happened
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Weights are on Hugging Face (BF16 and NVFP4 checkpoints), plus Amazon SageMaker AI, Google Cloud Model Garden and Microsoft Foundry Models.&lt;/li&gt;
&lt;li&gt;Hosted APIs launched the same day at Baseten, Fireworks AI, Groq, Modal, Nebius, OpenRouter and Together AI.&lt;/li&gt;
&lt;li&gt;It runs on SGLang, vLLM, TensorRT-LLM, Transformers, MLX, llama.cpp and Unsloth. Meta shows it running on two Apple M5 Ultra Mac Studios with 512 GB each.&lt;/li&gt;
&lt;li&gt;Architecture (Hugging Face model card): 256 experts per MoE layer, 8 routed per token; text, image, audio and video in, text out.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why people care
&lt;/h2&gt;

&lt;p&gt;Chinese labs (Qwen, Kimi, GLM) have led open weights for most of 2026. This is a US lab answering with a large, agent-focused model that you can actually download and self-host.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the coverage skips
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Active vs total parameters.&lt;/strong&gt; 42B active sets the compute per token. All 816B weights still have to sit in memory. The model card asks for roughly 700 GB of VRAM for NVFP4 and about 2 TB for BF16. Cheap per token is not cheap to host.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The license is not OSI open source.&lt;/strong&gt; The Muse Model License opens like MIT ("free of charge... without restriction"), then adds conditions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Section 2: any product that uses the model or a "Derivative" must prominently display "Built with Muse Spark Open" (UI, docs, website or settings).&lt;/li&gt;
&lt;li&gt;"Derivatives" includes any model "trained, modified (including fine-tuned), distilled, or otherwise improved using the Software or any outputs or results thereof". A small model you fine-tune on Muse outputs counts.&lt;/li&gt;
&lt;li&gt;Section 3: if you sell model access via an API ("Model as a Service") and your group's gross revenue passes $20 million in any 12 months, you must sign a separate agreement with Meta first. Internal use, research, and powering features of your own product are exempt.&lt;/li&gt;
&lt;li&gt;The attached Usage Policy rules out, among other things, operating critical infrastructure, transportation technologies or heavy machinery, and says the model is not intended for anyone under 18.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. The benchmarks are self-reported.&lt;/strong&gt; Meta says a fuller evaluation report is coming. Independent indexes so far place it behind the strongest Chinese open models on general intelligence scores.&lt;/p&gt;

&lt;h2&gt;
  
  
  Facts vs prediction
&lt;/h2&gt;

&lt;p&gt;Everything above comes from Meta's announcement, the Hugging Face model card and the license text. My read, a prediction rather than a fact: most teams will use it through hosted APIs, not local hardware, and the derivative clause will matter more than the $20M clause for small teams running distillation pipelines.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical takeaway
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Read LICENSE.md before you build anything on it, especially if you plan to distill or fine-tune on its outputs.&lt;/li&gt;
&lt;li&gt;Add the "Built with Muse Spark Open" line wherever you ship it.&lt;/li&gt;
&lt;li&gt;Run 20 to 50 of your own real tasks through a hosted endpoint before trusting any leaderboard.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Meta AI Research, Introducing Muse Spark Open (Oct 15, 2026): &lt;a href="https://research.meta.ai/blog/muse-spark-open" rel="noopener noreferrer"&gt;https://research.meta.ai/blog/muse-spark-open&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Muse Model License: &lt;a href="https://huggingface.co/meta-models/Muse-Spark-Open-816B-A42B/blob/main/LICENSE.md" rel="noopener noreferrer"&gt;https://huggingface.co/meta-models/Muse-Spark-Open-816B-A42B/blob/main/LICENSE.md&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Hugging Face launch post: &lt;a href="https://huggingface.co/blog/meta-muse-spark-open" rel="noopener noreferrer"&gt;https://huggingface.co/blog/meta-muse-spark-open&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This post was written with AI assistance and edited for accuracy.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>llm</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>NVIDIA Open-Sourced Run:ai. Here Is What Actually Changed for Kubernetes GPU Teams</title>
      <dc:creator>Clydara</dc:creator>
      <pubDate>Thu, 15 Oct 2026 14:08:56 +0000</pubDate>
      <link>https://dev.to/clydaralab/nvidia-open-sourced-runai-here-is-what-actually-changed-for-kubernetes-gpu-teams-522h</link>
      <guid>https://dev.to/clydaralab/nvidia-open-sourced-runai-here-is-what-actually-changed-for-kubernetes-gpu-teams-522h</guid>
      <description>&lt;p&gt;On October 13, 2026, NVIDIA released the full Run:ai GPU orchestration platform as open source, inside its new DSX AI Factory GitHub organization. Most coverage stopped at "NVIDIA open-sources Run:ai." The details matter more than the headline, so here is what shipped, why platform teams care, and what the announcement leaves out.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happened
&lt;/h2&gt;

&lt;p&gt;NVIDIA published the complete Run:ai platform code plus four components you can adopt on their own:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;KAI Scheduler&lt;/strong&gt;: the Kubernetes-native scheduler behind Run:ai. Gang scheduling, fair-share and quotas, topology-aware bin-packing, GPU sharing (MIG, MPS, time slicing, HAMi) and Dynamic Resource Allocation support. Apache 2.0 and a CNCF Sandbox project.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GPU Fractioning Operator&lt;/strong&gt;: wires CUDA-native GPU fractions into Kubernetes, with a per-pod metrics exporter. It is scheduler-agnostic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;KAI Resource Management&lt;/strong&gt;: projects, departments, hierarchical quotas and node pools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Workload Map&lt;/strong&gt;: a Go library that describes PyTorchJob, RayCluster, JobSet, KServe and custom CRDs once, so tools can schedule and observe them without hardcoding each type.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A Helm-installable "Community Product" build is also on NVIDIA NGC. Eight partners, including Crusoe, Mirantis, Nebius, Rafay, Spectro Cloud and vCluster, announced integrations the same day.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why people care
&lt;/h2&gt;

&lt;p&gt;GPU time is the most expensive line on most AI infrastructure bills, and plain Kubernetes was not designed to share GPUs fairly between teams. Until now, the org layer (who gets what share of the cluster) and fractional GPUs were the paid parts of Run:ai. Both are now code anyone can read, fork and run.&lt;/p&gt;

&lt;h2&gt;
  
  
  What could change
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Smaller AI clouds and internal platform teams get a production-tested quota and fair-share layer without a commercial contract. NVIDIA's own example: guarantee 50% of a cluster to research without letting any other team grab the rest.&lt;/li&gt;
&lt;li&gt;Fractional GPUs for notebooks and small models become easier to justify, because sharing no longer depends on a proprietary driver hook.&lt;/li&gt;
&lt;li&gt;Tooling vendors may converge on Workload Map instead of writing a private integration per CRD. That one is a prediction, not a fact: watch its ADOPTERS file.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What most coverage misses
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The fractioning code was retired, not opened.&lt;/strong&gt; NVIDIA says its proprietary fractional-GPU implementation has been retired in favour of native fractions in CUDA 13.4. The new operator is the Kubernetes glue for that driver feature, so check your CUDA and driver versions before planning around it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free does not mean supported.&lt;/strong&gt; The NGC Community build needs no Run:ai subscription, but NVIDIA states that enterprise support is not included, and downloading it means accepting NVIDIA's software license terms on top of the open source licenses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;KAI Scheduler was already open.&lt;/strong&gt; It went Apache 2.0 earlier; the genuinely new code is the platform layer, resource management, Workload Map and the operator.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You do not need the whole stack.&lt;/strong&gt; NVIDIA says KAI Scheduler can run in an existing cluster alongside your current software, and Workload Map works offline on unstructured objects.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Facts vs predictions
&lt;/h2&gt;

&lt;p&gt;Facts: the repositories, the four components, the CUDA 13.4 change, the NGC support terms and the partner list are all in NVIDIA's technical blog. Predictions: wider adoption by smaller clouds and convergence on Workload Map. Nobody has public adoption numbers yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to start
&lt;/h2&gt;

&lt;p&gt;If you run shared GPU nodes today, start with KAI Scheduler alone in a staging cluster, then try the fractioning operator on notebook workloads once your nodes are on a CUDA 13.4 capable driver.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sources:&lt;/strong&gt; &lt;a href="https://developer.nvidia.com/blog/nvidia-runai-is-now-open-source-as-part-of-nvidia-dsx-ai-factory-platform/" rel="noopener noreferrer"&gt;NVIDIA Technical Blog, Oct 13, 2026&lt;/a&gt; · &lt;a href="https://github.com/dsx-ai-factory/run-ai" rel="noopener noreferrer"&gt;dsx-ai-factory/run-ai on GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Which part would you actually adopt first: the scheduler, the quotas or the GPU fractions?&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This post was drafted with AI assistance and reviewed and edited by the Clydara team.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>opensource</category>
      <category>ai</category>
      <category>devops</category>
    </item>
    <item>
      <title>The iPhone Duo Web Checklist: 9 Things to Verify Before October 23</title>
      <dc:creator>Clydara</dc:creator>
      <pubDate>Tue, 13 Oct 2026 13:18:49 +0000</pubDate>
      <link>https://dev.to/clydaralab/the-iphone-duo-web-checklist-9-things-to-verify-before-october-23-54mk</link>
      <guid>https://dev.to/clydaralab/the-iphone-duo-web-checklist-9-things-to-verify-before-october-23-54mk</guid>
      <description>&lt;p&gt;In September, a post titled "Dear God websites look horrible on iPhone Duo" climbed to the top of r/webdev. Two screenshots and one complaint: with the phone closed, sites were using about 70% of the screen. It passed 3,000 upvotes. Much of the thread was aimed at Safari for keeping its controls on screen on the smaller, closed display. Fair. But plenty of the ugliness in those screenshots was ours: layouts built for three fixed widths.&lt;/p&gt;

&lt;p&gt;Pre-orders open October 16. The phone goes on sale October 23. Below is the checklist we'd work through before then. Nothing here assumes you own the device, because almost nobody does yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  First, the numbers (and why you shouldn't trust them)
&lt;/h2&gt;

&lt;p&gt;Apple publishes physical pixels only. The inner display is 1878 x 2670 and the outer one is 1398 x 2034. Divide by the usual iPhone pixel ratio of 3 and you get the commonly quoted estimates:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;State&lt;/th&gt;
&lt;th&gt;Screen in CSS px (estimated)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Closed, outer display&lt;/td&gt;
&lt;td&gt;about 466 x 678&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open, held like a book&lt;/td&gt;
&lt;td&gt;about 890 x 626&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open, rotated&lt;/td&gt;
&lt;td&gt;about 626 x 890&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The open device is wider than it is tall (164.6 mm by 117.8 mm), which is why most write-ups quote 890 as the unfolded width. So the jump people talk about, 466 to 890 in one motion with no reload, is real in the common case.&lt;/p&gt;

&lt;p&gt;Now the catch. Safari on the Duo keeps a strip of controls down the right edge. One design studio, working in Apple's iOS 27.1 simulator, measured the outer screen's web view at 466 points but the layout viewport at 382. That means &lt;code&gt;innerWidth&lt;/code&gt; may be smaller than every number in the table.&lt;/p&gt;

&lt;p&gt;Treat the table as a test plan. Never treat it as a breakpoint list.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Find out where your breakpoints actually land
&lt;/h2&gt;

&lt;p&gt;Default framework breakpoints were not designed with this phone in mind. At 890px, Tailwind and Bootstrap both serve their &lt;code&gt;md&lt;/code&gt; (768px) tier, which most teams treat as "tablet portrait". At 626px, Tailwind's first step (&lt;code&gt;sm&lt;/code&gt;, 640px) doesn't fire at all, so a 7.6-inch screen gets the exact CSS of a 6.3-inch iPhone.&lt;/p&gt;

&lt;p&gt;Paste this into DevTools on your production site to see what you're really shipping:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Lists every width breakpoint in same-origin stylesheets.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;widths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;skipped&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;walk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rule&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rule&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nx"&gt;CSSMediaRule&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="sr"&gt;/width/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;conditionText&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[,&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;conditionText&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;matchAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;(\d&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;(?:\.\d&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)?)(&lt;/span&gt;&lt;span class="sr"&gt;px|em|rem&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;widths&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;unit&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cssRules&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;walk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cssRules&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sheet&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;styleSheets&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;walk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cssRules&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;skipped&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;widths&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;skipped&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; cross-origin sheets skipped`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;skipped&lt;/code&gt; is above zero, the list is incomplete. Check where 382, 466, 626 and 890 fall. If two of them hit the same tier and the layout looks wrong at one of them, you've found your first bug.&lt;/p&gt;

&lt;p&gt;Don't fix it with &lt;code&gt;@media (width: 890px)&lt;/code&gt;. The next foldable will ship different numbers. Move the boundary to wherever your content starts to look cramped or stretched.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Let components respond to their container
&lt;/h2&gt;

&lt;p&gt;Page breakpoints answer "how wide is the window?" Most layout bugs on the Duo are really "how wide is this card?" Container queries answer that directly, and they keep working in Split View, where your page might be half the inner screen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.card-list&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;container&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cards&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="n"&gt;inline-size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@container&lt;/span&gt; &lt;span class="n"&gt;cards&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="err"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;34rem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12rem&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The card now goes side by side when its column has room, whether that's on an unfolded Duo, a laptop or a narrow sidebar. Forms, pricing tables and product grids benefit the most.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Stop sizing heroes with &lt;code&gt;100vh&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;vh&lt;/code&gt; maps to the large viewport, the size with browser UI retracted. On a 678px-tall outer screen, a &lt;code&gt;100vh&lt;/code&gt; hero with a headline, a subhead and a button can push the button below the fold.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.hero&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;min-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c"&gt;/* fallback for old browsers */&lt;/span&gt;
  &lt;span class="nl"&gt;min-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="n"&gt;svh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c"&gt;/* small viewport: never taller than what's visible */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.app-shell&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="n"&gt;dvh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;      &lt;span class="c"&gt;/* dynamic: follows toolbars as they move */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our rule: &lt;code&gt;svh&lt;/code&gt; for marketing heroes, &lt;code&gt;dvh&lt;/code&gt; for full-screen app shells, &lt;code&gt;vh&lt;/code&gt; almost nowhere. One caveat worth checking yourself: the same studio reported &lt;code&gt;100vh&lt;/code&gt; resolving to 598 on a 678px outer screen in the simulator, and said no CSS unit matched the visible height under Safari's floating toolbar. Open your hero in the simulator and look before you trust any unit.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. A wide screen is not a mouse
&lt;/h2&gt;

&lt;p&gt;At 890px, plenty of sites switch to the desktop nav. That nav usually opens on &lt;code&gt;:hover&lt;/code&gt;. On a touch screen, hover is emulated with an awkward tap, so the mega menu either flickers or never opens.&lt;/p&gt;

&lt;p&gt;Gate hover behaviour on the input type instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.nav-item&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;.submenu&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Works everywhere: keyboard focus and an explicit toggle */&lt;/span&gt;
&lt;span class="nc"&gt;.nav-item&lt;/span&gt;&lt;span class="nd"&gt;:focus-within&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;.submenu&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nc"&gt;.nav-item&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;data-open&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;.submenu&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Only real hover devices get hover menus */&lt;/span&gt;
&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hover&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;hover&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fine&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.nav-item&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;.submenu&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Bigger hit areas for fingers */&lt;/span&gt;
&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;coarse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.nav-item&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="nc"&gt;.nav-item&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;min-block-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2.75rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;hover&lt;/code&gt; and &lt;code&gt;pointer&lt;/code&gt; describe the primary input. If you need "does any input hover?", use &lt;code&gt;any-hover&lt;/code&gt; and &lt;code&gt;any-pointer&lt;/code&gt;. Apple says Apple Pencil support for the Duo arrives later this year, which is one more reason not to bake "this phone never hovers" into your JavaScript.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Make your JavaScript resize-safe
&lt;/h2&gt;

&lt;p&gt;CSS reflows on its own. JavaScript that measured once at load does not. Look for these in your codebase: &lt;code&gt;const isMobile = window.innerWidth &amp;lt; 768&lt;/code&gt;, chart libraries initialised with a fixed width, carousels that calculate slide counts on mount.&lt;/p&gt;

&lt;p&gt;Use a media query listener for layout modes and &lt;code&gt;ResizeObserver&lt;/code&gt; for element sizes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wide&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;matchMedia&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;(width &amp;gt;= 48rem)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;setLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isWide&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;documentElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;layout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;isWide&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;wide&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;narrow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;setLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wide&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;wide&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;change&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chartBox&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.chart-wrap&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ro&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ResizeObserver&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;chart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contentRect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;ro&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chartBox&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both are Baseline widely available. The harder bug is state. If your framework unmounts the mobile nav and mounts a desktop one at a breakpoint, the user unfolds the phone and loses whatever they typed, the open accordion and sometimes their scroll position. Prefer one component that restyles over two components that swap.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Delete user-agent layout branching
&lt;/h2&gt;

&lt;p&gt;The Duo identifies as an iPhone. Code like this serves your phone layout to a screen with room for a sidebar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Wrong on the largest iPhone Apple has made&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isMobile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/iPhone/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userAgent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Search your repo, your tag manager and your server templates for this pattern. Replace it with media queries, container queries, or &lt;code&gt;matchMedia&lt;/code&gt; checks that listen for changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Split your safe-area padding
&lt;/h2&gt;

&lt;p&gt;If you draw edge to edge, safe-area values only apply with &lt;code&gt;viewport-fit=cover&lt;/code&gt; in the viewport meta. On the Duo, the left and right insets are reported to differ, so the old shorthand that copies one value to both sides is a quiet bug:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* Before */&lt;/span&gt;
&lt;span class="nc"&gt;.toolbar&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;padding-inline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;safe-area-inset-left&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* After */&lt;/span&gt;
&lt;span class="nc"&gt;.toolbar&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;padding-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;safe-area-inset-left&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="nl"&gt;padding-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;safe-area-inset-right&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reports conflict on whether Safari's right-hand control strip shows up in these insets at all, so verify with your own eyes in the simulator. And keep your primary call to action out of the dead centre of wide layouts. That's where the fold runs, and right now CSS can't tell you exactly where it is.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Don't wait for fold detection
&lt;/h2&gt;

&lt;p&gt;The web has APIs for this: Viewport Segments (&lt;code&gt;horizontal-viewport-segments&lt;/code&gt;, &lt;code&gt;visualViewport.segments&lt;/code&gt;) and Device Posture. Chrome supports them on Android foldables. WebKit's standards-positions issue for Viewport Segments, filed in March 2024, is still open with no stated position. A commenter on that issue noted in September that the feature appears behind a flag in the iOS 27.1 simulator. Behind a flag means your visitors won't have it.&lt;/p&gt;

&lt;p&gt;Write the single-viewport layout first and treat segments as an extra:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;segments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;visualViewport&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;segments&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;segments&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;segments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;documentElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fold&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;split&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;documentElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  9. Test the unfold itself
&lt;/h2&gt;

&lt;p&gt;A static screenshot at 890px tells you very little. The bugs happen during the transition. Here's the loop we'd run:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In Chrome or Safari responsive mode, set 466 x 678. Open the menu, type into a form, scroll halfway down a long page.&lt;/li&gt;
&lt;li&gt;Without reloading, switch to 890 x 626. Then 626 x 890. Then back to 466.&lt;/li&gt;
&lt;li&gt;Check what survived: scroll position, form input, open menus, playing video, sticky headers.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Add a dev-only logger so you can see what fired and when:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ResizeObserver&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;viewport&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;innerWidth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;innerHeight&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;documentElement&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On a Mac, you can go further. Per one studio's walkthrough, the Duo only appears in the iOS 27.1 simulator, and Xcode 27 moves simulators into an app called Device Hub:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;xcrun simctl create &lt;span class="s2"&gt;"iPhone Duo"&lt;/span&gt; com.apple.CoreSimulator.SimDeviceType.iPhone-Duo com.apple.CoreSimulator.SimRuntime.iOS-27-1
xcrun simctl boot &lt;span class="s2"&gt;"iPhone Duo"&lt;/span&gt;
xcrun simctl openurl booted http://localhost:5173
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Safari's Develop menu on the Mac then attaches Web Inspector to the simulator page. Also drag the Split View divider through its full range, since that resizes your page to widths no device table lists.&lt;/p&gt;

&lt;h2&gt;
  
  
  The short version for site owners
&lt;/h2&gt;

&lt;p&gt;If you don't write code, ask whoever maintains your site two questions this week. What does our site look like at 466 and 890 pixels wide? And what happens to a half-filled enquiry form when the phone opens? Layout bugs like these rarely throw errors. They just lose leads quietly, which is the same pattern behind most of the &lt;a href="https://www.clydralab.com/blog/startup-website-mistakes" rel="noopener noreferrer"&gt;reasons startup websites fail to generate leads&lt;/a&gt; that we've written about before.&lt;/p&gt;

&lt;p&gt;Which of these bit you first? We're especially curious whether anyone has a clean answer for Safari's side strip yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Apple Newsroom, iPhone Duo announcement (dates, displays, Split View, Apple Pencil): &lt;a href="https://www.apple.com/in/newsroom/2026/09/apple-unveils-iphone-duo" rel="noopener noreferrer"&gt;https://www.apple.com/in/newsroom/2026/09/apple-unveils-iphone-duo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Apple, iPhone Duo tech specs (pixel dimensions, physical size): &lt;a href="https://www.apple.com/iphone-duo/specs/" rel="noopener noreferrer"&gt;https://www.apple.com/iphone-duo/specs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;screensize.io, iPhone Duo viewport estimates: &lt;a href="https://www.screensize.io/blog/iphone-duo.html" rel="noopener noreferrer"&gt;https://www.screensize.io/blog/iphone-duo.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;MDN on viewport units, container queries, &lt;code&gt;hover&lt;/code&gt;, &lt;code&gt;pointer&lt;/code&gt;, &lt;code&gt;ResizeObserver&lt;/code&gt;: &lt;a href="https://developer.mozilla.org/" rel="noopener noreferrer"&gt;https://developer.mozilla.org/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;WebKit standards position on Viewport Segments: &lt;a href="https://github.com/WebKit/standards-positions/issues/327" rel="noopener noreferrer"&gt;https://github.com/WebKit/standards-positions/issues/327&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Written by the team at Clydara, a web and software studio in Lahore that builds and fixes sites like these for clients. We used AI tools to help with research and drafting, and checked every claim against the sources above.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>css</category>
      <category>javascript</category>
      <category>frontend</category>
    </item>
  </channel>
</rss>
