Sane Coding Blog Notes on Sane C++ Libraries and practical systems work.

☀️ Sane C++ June 26

Welcome to the June 2026 update! This month is about cleaner common foundations, more dependency-free libraries, agent-friendly repository workflows, Windows long-path support, and a large pass on Async contracts.

Common Foundations

June started with a fairly deep cleanup of the lower layers of the project. The old shape was that many libraries depended on Foundation even when they only needed a small primitive such as Result, Span, Function, compiler macros, platform detection, or a basic string/path view.

That is much cleaner now. A large set of these small building blocks has been moved into common fragments, so libraries can include only the pieces they actually need. The practical consequence is important: many more libraries now have no real library dependency at all.

Sane C++ Libraries dependency graph for June 2026

This fits the direction I want for Sane C++ Libraries. The libraries should be easy to pick up individually, easy to amalgamate, and easy for tools or agents to reason about without dragging a large conceptual dependency tree behind every include. Smaller dependency surfaces also make the single-file outputs less surprising, because the generated order is closer to the actual code structure.

Plugin and SerializationText also got dependency simplifications in the same spirit. They no longer need to pull in Strings, which removes another bit of unnecessary coupling from libraries that should stay small and composable.

There were also follow-up fixes around per-library assert providers, documentation, CI, and the JavaScript single-file generation path.

Detailed list of commits:

Agentic Repository Workflow

Another theme this month was making the repository easier to navigate and change with agents.

The documentation now has an explicit agentic contribution workflow. The website tagline also moved toward the "built for Agents" direction, and the documentation CI can trigger publishing of the website source.

This matters because I think that the era of manual coding is over (excluding recreative purposes of course).

Humans and agents both need routes through the codebase: library docs, skills, examples, local AGENTS.md and more, all pointing in the same direction.

I plan to expand more on this theme in the coming months, adding more formal constraints and ADR to prevent agents from derailing.

Detailed list of commits:

Windows Long Paths

Windows long paths also deserve their own section. This work started right at the end of May and carried into June with follow-up fixes, documentation, and build-tool integration.

The short version is that Windows runtime targets are now long-path-aware by default where it makes sense. SC::Build can emit the manifest support needed for console executables, GUI applications, and shared libraries, while static libraries reject that option because there is no runtime manifest to embed.

There is common Windows path handling, long-path-aware bootstrap behavior, PowerShell launcher support, Visual Studio project generation support, native build command rewriting, manifest/resource staging, and test coverage around long directory names.

Hopefully now this just works transparently without too many issues (and if there are, just as your agent to report them).

Detailed list of commits:

Async Contracts

The biggest library-specific work this month was Async. May introduced Await as a coroutine layer on top of Async, so June spent a lot of time tightening the lower-level contracts that everything else depends on.

The new AsyncContractTest is the clearest sign of that shift. Instead of only testing individual operations, the test suite now captures more of the lifecycle rules around event loops, requests, close paths, cancellation state, manual completions, sequence shutdown, submitted request stops, blocking polls, and request reuse from callbacks.

AsyncFilePoll was also split into AsyncFileReadiness and AsyncExternalCompletion. That is a better separation: one concept is about file readiness, while the other is about manually injecting completions into the event loop. Those were related implementation paths, but they are not the same API idea.

There was also a lot of wording cleanup in the docs. Signal fanout, signal option semantics, request enumeration, event-loop run behavior, and thread-pool policy are all more explicit now. That should help both direct Async users and the newer Await layer avoid relying on behavior that was accidental or underspecified.

Detailed list of commits:

Http, HttpClient and Everything Else

The rest of the month is mostly hardening and small practical fixes.

Http and HttpClient got a lot of edge-case coverage. Most of this is diagnostic and validation work: pinned error messages, disabled upload policies, multipart behavior, router and header helpers, WebSocket frame/hub diagnostics, server parser behavior, client TLS diagnostics, URL and proxy validation, authorization origin checks, cookie scope, and response header length limits.

That may sound less exciting than adding new HTTP features, but it is the work that makes the newer HTTP surface safer to build examples on. May made the HTTP libraries more useful; June made more of their failure modes explicit.

There were also smaller platform and tooling fixes. Process has a larger Windows environment arena, FileSystemWatcher handles zero-byte Windows change completions, SCExample is a little more robust around plugin files and example paths, the Windows bash launcher forwards to SC.bat, Visual Studio LLVM tool discovery was fixed in CI, and Time avoids an integer conversion warning.

Detailed list of commits:

See you next month!