On October 18, right in the middle of shipping a multi-feature audit and a supplement tracker redesign on my personal life_os_app (my daily Flutter Web + Cloud Firestore operating board), GitHub Actions stopped scheduling jobs. The billing meter for my personal account's hosted runner minutes had hit 100%.
Look at what my .github/workflows/ci.yml and deploy-live.yml were doing on every push and pull request:
ubuntu-latest VM.flutter analyze and 466 widget and accessibility tests (~110s).flutter build web --release --no-web-resources-cdn (~140s).google-github-actions/auth@v2) and deploying to Firebase Hosting target board (~35s).That is 6.5 minutes per PR push and another 4 minutes on merge to main. Across 70+ PRs in October, a single-developer personal project burned through thousands of CI minutes doing work my local Apple Silicon MacBook finishes in under 35 seconds.
When your CI budget hits zero on a personal repo, you have two choices: pay for extra runner minutes to compile code your laptop already compiled, or build a deterministic local verification and deployment pipeline that is faster and safer than the YAML workflow it replaces.
Here is the exact architecture I use to keep life_os_app shipping to Firebase Hosting and Cloud Firestore with zero GitHub Actions spend.
Moving deploys to your local machine only works if you never deploy unverified state. In life_os_app, the application state is split across two runtimes:
tool/board_*.py): Morning and evening scripts that pull from Apple Reminders, Google Calendar, Harvest, Notion, and GCP Billing, then write structured JSON documents into Cloud Firestore over REST.lib/): A Riverpod 3 + Material 3 multi-skin web app served from Firebase Hosting with a custom offline Service Worker (web/offline-sw.js).One of the biggest risks of running CLI sync tools outside a container is accidentally clobbering fields that the Flutter Web client writes directly from the browser. For example, on the Events and Admin tabs, I tick tasks directly in the UI (config/events.taskTicks and config/admin.done), while tool/board_events.py and tool/board_admin.py sync metadata from Notion and GCP Billing.
To prevent a CLI run from wiping browser taps, tool/board_firestore.py enforces two rules before any HTTP PATCH leaves the machine:
dayPlans, stats, config, finance, plan).?updateMask.fieldPaths=...) plus hard blocks against overwriting client-owned map keys:
# tool/board_firestore.py
if path == "config/events" and "taskTicks" in data and not fields:
raise SystemExit(
"refusing to overwrite config/events.taskTicks without --fields; "
"pass --fields updated,source,events"
)
if path == "config/admin" and "done" in data and not fields:
raise SystemExit(
"refusing to overwrite config/admin.done without --fields"
)
In addition, caching the gcloud auth print-access-token call with @functools.lru_cache(maxsize=1) and enforcing a 15-second socket timeout cut multi-document Firestore sync latency by 80% and eliminated hanging background processes when switching Wi-Fi networks.
In Cloud Firestore, a single malformed field inside one historical document in a collection query (collection('dayPlans').snapshots()) will normally throw a FormatException or TypeError inside .map(), killing the entire StreamProvider and replacing your UI with an error state.
During my audit pass, I hardened every repository to isolate decoding per document:
// lib/features/day_board/data/board_repository.dart
List<T> _decodeEach<T>(
QuerySnapshot<JsonMap> query,
T Function(JsonMap data, String id) decode,
) {
final results = <T>[];
for (final doc in query.docs) {
try {
results.add(decode(doc.data(), doc.id));
} on Object catch (error, stackTrace) {
developer.log(
'Skipping malformed document ${doc.reference.path}',
name: 'day_board.repository',
error: error,
stackTrace: stackTrace,
);
}
}
return results;
}
When saving multi-day edits (such as editing 7 days of focus blocks and habit notes in the This Week sheet), replacing 14 sequential await set() calls with a single atomic WriteBatch (saveWeekEditsBatch) eliminated partial-save race conditions on flaky mobile connections.
--no-web-resources-cdn) & Service Worker Cleanup
When deploying Flutter Web to Firebase Hosting for daily use on iPhone, iPad, and desktop, CDN font/CanvasKit fetches can stall on airplane or train Wi-Fi. Building with --no-web-resources-cdn bundles CanvasKit and font assets directly into build/web/, paired with a custom web/offline-sw.js that races network against a 3.5-second timeout before falling back to cache:
// web/offline-sw.js
function networkFirst(request, timeoutMs) {
return new Promise((resolve, reject) => {
const timer = setTimeout(() => reject(new Error('timeout')), timeoutMs);
fetch(request)
.then((response) => {
if (response && response.ok) {
caches.open(CACHE).then((cache) => cache.put(request, response.clone()));
}
resolve(response);
})
.catch(reject)
.finally(() => clearTimeout(timer));
}).catch(() => caches.match(request));
}
Notice the .finally(() => clearTimeout(timer)) cleanup: without it, every fast network response leaves an orphan timer running until timeoutMs expires.
| Stage | GitHub Actions (ubuntu-latest) |
Local Apple Silicon Gate | Improvement |
|---|---|---|---|
Python CLI Unit Tests (68 tests) |
14.2s (with setup) | 0.02s | 710x faster |
Dart Format + Analyze + 466 Flutter tests
|
118.0s | 14.5s | 8.1x faster |
flutter build web --release --no-web-resources-cdn |
142.0s | 14.8s | 9.6x faster |
firebase deploy --only hosting:board |
34.0s | 3.1s | 11.0x faster |
| Total Wall-Clock Time | ~5m 08s (plus SDK cache) | ~32.4s | ~9.5x faster, $0 CI cost |
Table totals exclude the Flutter SDK download and Pub cache warm-up (~90s), which is what brings a full PR run to ~6.5 minutes.
dart format -l 120 lib/ test/ && flutter analyze && python3 -m unittest discover -s tool -p '*_test.py' && flutter test) guarantees parity before firebase deploy.hosting:board, hosting:board-staging). Mapping targets in .firebaserc lets you preview on staging or promote to live with --only hosting:board without touching sibling sites on the same GCP project..fromJson() calls inside a helper that logs to dart:developer and skips the corrupted record.flutter test, not in production. Running textContrastGuideline and androidTapTargetGuideline with GoogleFonts.config.allowRuntimeFetching = false catches neon text shadow contrast drops and 32pt icons in milliseconds.The complete local release gate in one command:
dart format -l 120 lib/ test/ && \
flutter analyze && \
python3 -m unittest discover -s tool -p '*_test.py' && \
flutter test && \
flutter build web --release --no-web-resources-cdn && \
firebase deploy --only hosting:board --project esra-life-os
Since the mid-1990s, every desktop and laptop PC has followed the exact same blueprint: an x86 CPU connected to system RAM on one side, and a discrete GPU wired to separate VRAM across a narrow PCIe bus on the other. While that split architecture powered three decades of spreadsheets, web browsers, and rasterized games, it hits a brick wall when you try to run a 120-billion-parameter AI agent locally on your desk.
With the rollout of the NVIDIA DGX Spark and GB10 Grace Blackwell Superchip alongside the Windows-powered RTX Spark (N1X) platform, NVIDIA CEO Jensen Huang has declared the end of thirty years of traditional PC architecture. In this hardware guide, we examine why the split CPU-GPU memory wall is dead, how NVLink-C2C unifies 128 GB of memory on a single 3nm chip, and how local autonomous agents reshape your next PC.
To understand why NVIDIA declared the traditional PC architecture obsolete, look inside any high-end desktop or gaming laptop built since 1995. Even if you install 128 GB of DDR5 system memory alongside an flagship discrete graphics card on a modern Windows 11 developer workstation, your GPU can only address its own soldered 16 GB or 24 GB pool of GDDR VRAM at full speed.
Whenever a local LLM or 3D scene exceeds that 16 GB VRAM ceiling, the system shuttles tensors across the slow PCIe bus. As software shifts from static chat to always-on agentic AI, PCs no longer just await mouse clicks.
Instead of manually clicking menus, autonomous local agents observe your screen, orchestrate tools like Rhino, Blender, and Visual Studio, and hold 120-billion-parameter weights plus 1-million-token context windows directly in unified memory.
NVIDIA demolishes the PCIe memory wall by bringing its data-center superchip design down to personal computers through the NVIDIA GB10 Grace Blackwell Superchip and the closely related NVIDIA RTX Spark (N1X) SoC. Co-engineered with MediaTek on TSMC's 3nm process with 70 billion transistors, the silicon integrates thirty years of CUDA, RTX ray tracing, and Tensor Core engineering onto a single package.
On the compute side, the chip pairs a custom 20-core Armv9.2 Grace CPU (configured with 10 high-performance Cortex-X925 cores clocking up to 4.1 GHz and 10 high-efficiency Cortex-A725 cores) with a Blackwell GPU packing 6,144 CUDA cores, 5th-Gen Tensor Cores, and 4th-Gen RT Cores. Rather than communicating over a slow PCIe lane, the Grace CPU and Blackwell GPU connect via NVIDIA NVLink-C2C chip-to-chip interconnect.
This NVLink-C2C fabric gives both the CPU and GPU zero-copy, cache-coherent access to a single 64 GB or 128 GB 256-bit LPDDR5X unified memory pool delivering 273 GB/s to 300.8 GB/s of bandwidth. Rated at up to 1 petaFLOP of sparse FP4 AI performance within a 45W–80W laptop envelope (or 140W TDP in compact desktops), an RTX Spark laptop like the Microsoft Surface Laptop Ultra can render a 90 GB 3D OptiX scene, decode 12K 4:2:2 video, run AAA games at 1440p over 100 FPS with DLSS 4.5 Ray Reconstruction, and host a 120B LLM simultaneously.
Dropping 128 GB of coherent unified memory into a laptop required Microsoft and NVIDIA to re-architect core memory and scheduling subsystems inside Windows 11 26H2. Microsoft lifted the legacy Windows upper limit on system memory addressable by the GPU, introduced large shared-memory page management so CPU and GPU tasks dynamically partition memory without page-table thrashing, and built a heterogeneous 20-core workload profile scheduler backed by the Microsoft Power and Thermal Framework.
Meanwhile, the Windows 11 Prism emulator runs x86 apps alongside native Arm64 builds of Blender, Premiere, and Easy Anti-Cheat, while developers migrate legacy x86 code to Arm via the Model Context Protocol (MCP).
Because an autonomous desktop agent can read local files and control applications, running agents without OS-level containment is a massive security risk. NVIDIA and Microsoft solved this by introducing new Windows security primitives alongside the NVIDIA OpenShell sandboxed agent runtime and the NemoClaw open agent blueprint stack—which enforce strict user-defined privacy policies, isolate local agent execution, and strip personal data before escalating complex queries to cloud models.
For AI researchers, data scientists, and robotics engineers who prefer an Ubuntu-based Linux environment that mirrors data-center clusters, the NVIDIA DGX Spark packs the GB10 Grace Blackwell Superchip, 128 GB of coherent unified memory, and up to 4 TB of self-encrypting NVMe storage into a 1.2 kg palm-sized chassis running NVIDIA DGX OS. Out of the box, a single DGX Spark fine-tunes models up to 70 billion parameters and runs local inference on models up to 200 billion parameters.
Even more impressively, every DGX Spark includes dual rear QSFP ports powered by an integrated NVIDIA ConnectX-7 SmartNIC running at 200 Gbps. Using the NVIDIA Sync Cluster Assistant, you can link two DGX Spark boxes directly with a single QSFP112 DAC cable (no network switch required) to create a 256 GB desktop cluster for 400B-parameter models, or connect four units through a 200 GbE RoCE v2 switch to unlock 512 GB of unified memory for 700-billion-parameter frontier models.
Whether you build enterprise .NET microservices, 3D pipelines, or local AI agents in Kolkata or Bengaluru, you can prepare your engineering stack for unified-memory Arm PCs using four practical steps:
Just as smartphones transformed mobile phones from voice-call handsets into pocket computers, NVIDIA's GB10 and RTX Spark architecture transforms the personal computer from a manual application launcher into an autonomous agent workstation. By fusing a 20-core Arm Grace CPU, a 6,144-core Blackwell GPU, and 128 GB of coherent unified memory over NVLink-C2C, the thirty-year-old PCIe memory bottleneck is officially history.
If your daily workflow involves local LLM fine-tuning, multi-agent orchestration, or massive 3D rendering scenes that choke a 16 GB or 24 GB discrete graphics card, unified-memory Grace Blackwell desktops and laptops represent the biggest architectural leap since 1995.
Manufacturers don't have to choose between running AI agents in the cloud or on site. A hybrid model uses one agent framework, built on common data contracts and guardrails, so the same agent runs in the cloud, at the edge, or fully disconnected, with every instance managed through a single interface.
Christoph Berlin, Vice President of Engineering for Cloud and AI at Microsoft, picks up from Part 1's root cause example to tackle scale: how to run an agent across many sites without building it over and over. He closes with two lessons for agentic AI in manufacturing.
Resources
- Microsoft for Manufacturing https://www.microsoft.com/AI/manufacturing
- More Azure resources! https://azure.com/AzureEssentials
Connect
- Christoph Berlin https://www.linkedin.com/in/christophberlin
Chapters
0:00 Why manufacturers can't run every AI agent in the cloud
1:10 Should AI agents run in the cloud or at the edge?
1:49 How a blueprint makes AI agents repeatable
2:25 How one AI agent runs across hundreds of sites
3:04 Two lessons for scaling agentic AI in manufacturing
In the previous episode, we covered organizational culture, including why posters aren’t the way to change culture, crucial theoretical foundations from Douglas McGregor and Ron Westrum, the impact of arbitrary deadlines, and why feedback keeps organizations healthy.
This episode examines Platform Engineering and the persistent debate between mandatory and optional adoption strategies. The episode was inspired by data from our Future of Platform Engineering report.
You can watch the episode below, or read on to find some of the key discussion points.
Watch Continuous Delivery Office Hours Ep.12
Mandatory platforms have been an issue in the past, with platform producers and consumers diverging dramatically on whether a platform is successful. Part of the perception gap comes down to platform teams losing the adoption signal: if everyone must use the platform, you’ve lost a way to discover gaps and flaws in what you provide.
Since then, platforms have become broader. Platforms now have almost 6x as many features as they did when the perception gap was present. As platforms take on tasks that developers truly appreciate, like security and compliance, the gap between producers and consumers has closed.
You might think of this like the difference between being forced to use a bicycle to travel both before and after the invention of the bicycle saddle. Riders are far happier to be forced to cycle when they have a cushioned seat.
Alongside the dissipation of perceptual differences, it turns out mandatory platforms outperform optional platforms in terms of goal attainment. However, there are many factors contributing to platform success, like monitoring developer satisfaction and regularly eliciting feedback to help improve the platform.
The other factors of platform success have more impact, and you should still consider optional adoption, but combined with mandatory policies. That means development teams have to meet the same standards they would meet if they adopted the platform, which makes platform adoption more appealing and less likely to cause conflict or friction.
The most common number of features baked into a platform was four, but that has grown to 24. Platforms are getting broader, and these wider platforms are more successful than the tiny ones of the past. Despite this link between platform breadth and goal attainment, it’s important to bear in mind that the volume of features alone is not a sufficient strategy, and that choosing to solve the right problems is the path to success.
Maintaining regular contact with developers, lightly assessing their satisfaction with the platform, and dedicating time to conversations that shape your platform’s direction are all part of the high-performance platform playbook. The usefulness comes from solving the right problems, and you need to focus on developer needs to make the right choices.
Platform teams are rediscovering many of the capabilities of the State of DevOps research and its associated model, like Lean Product Management, which prove useful in building platforms as internal products.
Unsurprisingly, platforms that meet more goals have higher budget safety. They are showing a return on investment, so they can be confident in maintaining their funding over the long run. Platforms that fail to meet their goals are more likely to have their budgets redirected to other initiatives.
Platform teams need to show the value back to the organization in terms the organization understands and for measures it cares about. With AI initiatives soaking up money, some organizations will start reallocating funds and focus, leaving platforms underfunded or dropped.
Some of the best platforms will be invisible in daily use because developers don’t have to keep interacting with them. These boring, invisible platforms are the most valuable, but the least visible. Providing metrics and proof of value for these platforms will keep them funded.
Happy deployments!
Continuous Delivery Office Hours is a series of conversations about software delivery, with Tony Kelly, Bob Walker, and Steve Fenton.
You can find more episodes on YouTube, Apple Podcasts, and Pocket Casts.
In this point release, we kept focussing on improving decompilation accuracy and performance (raw performance as well as memory usage) across the board. This is why again a lot of work went in the category Testing / Infrastructure.
One major performance win to point out is that we now ship ilspycmd with native AOT packages for linux-x64 and win-x64. Measured on win-x64 against the same 3 MB input (ICSharpCode.Decompiler.dll), medians of five runs:
| Call shape | managed tool | AOT package |
|---|---|---|
--version |
219 ms | 45 ms |
-l c (list classes) |
384 ms | 93 ms |
--type one large class |
1,446 ms | 199 ms |
--type one small class |
1,797 ms | 315 ms |
-p whole project (881 files) |
6.3 s | 2.9 s |
For an agent loop that spawns ilspycmd per question that is a 4x to 7x reduction per call!
value.<Clone>$() into value with {} even if there are no initializersFor a full list of changes click here.
This release is based on .NET 10.0. Please make sure that you have it installed on your machine beforehand.
Note for Mac users: see https://github.com/icsharpcode/ILSpy/wiki/Build-Artifacts#running-the-macos-artifact because the ILSpy.app is neither signed nor notarized.
Want to learn how we do PR reviews these days? Check out Stampeded.