Sr. Content Developer at Microsoft, working remotely in PA, TechBash conference organizer, former Microsoft MVP, Husband, Dad and Geek.
155636 stories
·
33 followers

v2026.6.6

1 Share

openclaw 2026.6.6

Read the whole story
alvinashcraft
just a second ago
reply
Pennsylvania, USA
Share this story
Delete

Understanding the rationale behind a rule when trying to circumvent it

1 Share

In the documentation for best practices for implementing process and thread-related callback functions, it calls out

  • Keep routines short and simple.
  • Don’t make calls into a user mode service to validate the process, thread, or image.
  • Don’t make registry calls.
  • Don’t make blocking and/or Interprocess Communication (IPC) function calls.
  • Don’t synchronize with other threads because it can lead to reentrancy deadlocks.

So far so good. It seems that these callback functions need to operate quickly and cannot block. These are callbacks that are invoked when a process starts or exits, when a thread starts or exits, when a DLL or EXE is loaded or unloaded, and various other low-level events.

The various prohibitions above suggest that these callouts are called during the process creation/termination sequence, so if you take a long time to deal with them, you are slowing down the entire system. And the rather extreme requirements, like “Don’t make registry calls,” suggest that they might even be called while the system holds internal locks.

The list of best practices continues:

  • Use System Worker Threads to queue work especially work involving:
    • Slow APIs or APIs that call into other process.
    • Any blocking behavior that could interrupt threads in core services.

Okay, so this is providing a suggestion on how you can offload expensive work to code running outside the callback. This once again highlights that the callback itself needs to be fast with minimal blocking.

My colleagues in enterprise support often run into cases where the reason for a system hang is a driver violating the rule that these callbacks must return quickly. For example, a common anti-pattern is a driver whose callback starts by following the guidance above to queue work to a System Worker Thread, but then they block until the work item completes.

This is a case of following the rules without understanding why the rules are there.

The rule is that the callback needs to be fast and return quickly. The driver followed the letter of the law by delegating the work to a System Worker Thread, and there’s no rule that says “Don’t wait for work items”, so they must have figured that this gave them a loophole for executing synchronous long-running work.

But the rules “Don’t make blocking and/or Interprocess Communication (IPC) function calls” and “Don’t synchronize with other threads because it can lead to reentrancy deadlocks” make it clear that you shouldn’t be blocking in your callback for extended periods of time. The “Don’t”s are just calling out some common ways that your callback can block.

And it looks like the documentation was updated in 2020 to call out this specific case:

  • If you use System Worker Threads, don’t wait on the work to complete. Doing so defeats the purpose of queuing the work to be completed asynchronously.

One could argue that this rule is already covered by the “Don’t synchronize with other threads” rule, but I guess the driver vendor interpreted it as “But I’m not synchronizing with another thread. I’m synchronizing on an event!” But of course, the event is set by another thread, so you are effectively synchronizing with another thread.

My colleague in enterprise support describes this as the “It wasn’t me, it was my brother” excuse. You are told by your parents not to turn on the television set, so you tell your brother to do it. Technically, you didn’t turn the television set on, but in effect, you did because your brother is acting under your instructions. (This is why contracts often contain wording like “may not disclose or cause to be disclosed,” so that you can’t say “No, I totally didn’t disclose it. I gave the information to Bob, and it was Bob who disclosed it!”)

The documentation should open with something like this:

The callback function must perform its work quickly without blocking. If you need to do complex work or synchronize with other threads or processes, do the work asynchronously, such as by using System Worker Threads.

And then it can give a list of examples of things that count as blocking.

Some examples of blocking that is not allowed from the callback function:

And then it can follow up with additional constraints.

Furthermore, the callback function may not perform any of the following operations:

The post Understanding the rationale behind a rule when trying to circumvent it appeared first on The Old New Thing.

Read the whole story
alvinashcraft
17 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

Agentic AI: The need for a data foundation

1 Share
This is the first post of the 4-part series on Agentic Data Infrastructure.Every business app now ships with an AI agent. Each one is good at its own job. The problem is, none of them talk to each other. Your helpdesk agent doesn't know about overdue invoices. Your CRM agent may not know about open support escalations. Each agent sees a slice of...

Read the whole story
alvinashcraft
28 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

VS Code 1.124 Focuses on Agent Autonomy and Parallel Sessions

1 Share
Microsoft's June 2026 VS Code update turns on Autopilot by default and adds background sending for agent sessions.
Read the whole story
alvinashcraft
2 hours ago
reply
Pennsylvania, USA
Share this story
Delete

The Runtime Is Free Now. The Harness Is the Business.

1 Share

View all my published articles

Six months ago, Microsoft’s posture toward OpenClaw read as containment. According to multiple accounts, internal security guidance treated the open-source agent runtime as untrusted code that executed with persistent credentials, and Satya Nadella reportedly compared ungoverned deployments to a virus. Hold those two lines loosely, since they trace to secondary reporting rather than anything Microsoft published. The posture they describe was real either way. The official enterprise answer to “can I run this at work” was no.

Last week at Build, Microsoft shipped Scout, its first always-on agent, and built it on OpenClaw. Then it went further. It announced that it is contributing its policy conformance system directly upstream to the open project, so any organization running OpenClaw can validate its environment against security and compliance requirements and receive an audit-ready answer. That description comes from Microsoft’s own launch post, not from analyst spin.

The runtime Microsoft could not stop, it decided to standardize. That reversal is the story, and it carries a specific message for everyone building agents in regulated industries: the largest enterprise software company on earth just told the market that the agent is a commodity and the harness is the business.

What actually shipped

Scout is the first of a category Microsoft calls Autopilots: agents that run continuously rather than per-session, hold state, and operate across Teams, Outlook, OneDrive, and SharePoint. It is rolling out through the Frontier early-access program, desktop first. Under the hood is OpenClaw, the runtime Peter Steinberger assembled in late 2025, which went from weekend project to default substrate of the agent world in roughly six months.

Microsoft is not alone in the bet. Google shipped Gemini Spark on the same foundation days earlier, and Meta is reportedly close behind with Hatch. Three platform companies converging on one open runtime inside a single quarter is not sentiment. It is a verdict on where the value is not.

Why give away the good part

The New Stack published the sharpest read of the launch, and the analogy holds: this is Android again. Google made the base operating system a free common layer, and the money moved up the stack, into managed identity, device management, and the consoles enterprises actually pay for. The agent loop itself- read context, plan, call tools, write output- is heading the same direction. OpenClaw already does it well enough that Microsoft chose not to rebuild it.

Their illustration, which I will borrow and then transpose: picture an agent that reconciles invoices overnight. The reconciliation loop is solved; the open runtime handles it today. What stands between that agent and a production ledger is everything else. The company needs an identity it can name, a boundary that keeps the agent out of every system except accounts payable, and a record an auditor can reconstruct the next morning. The runtime supplies none of that. The layers above it do, and those layers are exactly what Microsoft kept: Agent 365, execution containment, the management plane.

What “policy conformance upstream” actually means

For the harness developers reading this, the substance matters more than the strategy. The control surface Microsoft describes has four parts. Agent identity, so every action has a named actor behind it. Scoped access, so the agent reaches only the resources and destinations the organization approved. Human approval gates on consequential actions, enforced before execution rather than logged after. And inline data protection, with sensitivity labels and loss-prevention policy applied at the moment of a write or send, not in a retrospective report. Conformance is the layer that checks a live deployment against those requirements and produces evidence of its passing.

Two implications follow if harnesses are your work.

First, the build-versus-buy line just moved. The bespoke validation scripts every serious OpenClaw shop has been writing by hand, the “is this deployment configured safely” code, become redundant as the upstream conformance layer matures. The durable work shifts to policy content: the baselines, the packs, the mappings from control to evidence that the conformance layer evaluates. Write policy, not plumbing.

Second, the timing is not subtle. The same week Scout launched, researchers disclosed five critical zero-days in OpenClaw’s allowlist identity resolution across a half dozen messaging surfaces. That is not an argument against the runtime. It is the argument for conformance. When the substrate moves this fast, you need a standard, repeatable way to prove your deployment is not the vulnerable configuration, and you need it on every release, not once a year during audit season.

The healthcare transposition

Now swap the invoice for a chart.

A patient agent that assembles a visit summary or drafts an amendment request after an AI scribe writes something wrong in a clinical note is not hard at the loop level. Tula does the first in about thirty seconds. What a health system needs before any agent touches PHI is the finance list with sharper teeth: an agent identity tied to an accountable person, access scoped to the minimum necessary record set, a human gate on anything that writes toward the legal record, and an audit trail that satisfies not just a CISO but a CMS surveyor or an OCR investigator. Patients exercising their right to amend under 164.526 deserve the same chain of evidence from their side of the portal.

Generic conformance gives you the substrate. It cannot tell you what counts as a sensitive action inside a clinical workflow, which evidence artifacts an auditor will actually accept, or how an amendment request must be tracked from submission to disposition. That is domain semantics, and it is the layer I have been calling the Fourth Tier: governed, domain-specific agents that sit above the runtime, the framework, and the generic harness. Microsoft just poured concrete under the first three tiers. The fourth is still open, and in healthcare it is still mostly empty.

Disclosure, because you should know where I sit: Tula, the open-source patient agent we released in May, runs on OpenClaw under an MIT license, and RealActivity’s compliance agents are built on the same runtime. When Microsoft puts platform engineering into the governance substrate of that runtime, the work compounds downstream, all the way to a patient agent running on a Medicare beneficiary’s laptop. I am long this thesis in the most literal way available.

Three moves

If you build agents in health and life sciences, three things follow.

Track the conformance work as it lands upstream, and build against it rather than beside it. Restructure your environment checks as policy packs the conformance layer can evaluate, so your controls inherit every improvement Microsoft ships instead of competing with them.

Stop spending innovation budget on substrate. Identity plumbing, containment, base audit logging: that work is being commoditized in public by companies with more engineers than you will ever hire. Your differentiation is policy content and the evidence model behind it, the parts that require knowing how a health system actually gets audited.

Pressure-test the phrase “audit-ready.” It means different things to a CISO, a HIPAA privacy officer, and a CMS surveyor. Map the conformance layer’s output to the artifacts your compliance team files today. Wherever there is a gap, that gap is your roadmap.

The harness was the bet

I have spent the past year making one argument: the agent was never the risk; the harness was. At Build, Microsoft made that argument for me, with a shipping product, an upstream contribution, and a 2026 roadmap priced around it. The runtime is free now. The harness never will be.

Vibes are becoming verifiable. This time it is on Redmond’s calendar too.


I will be going deeper on this on July 31 at M365 Community Days NYC, presenting “From Vibes to Verifiable” at Microsoft, 11 Times Square.

Sources


Paul J. Swider is CEO and Chief AI Officer at RealActivity, a Microsoft Partner specializing in mission-critical AI for healthcare systems. He has 30+ years in healthcare technology, has trained over 3,000 engineers across GE, IDX, and Microsoft, and is the founder of BOSHUG, the Boston Healthcare Cloud & AI Community spanning 50+ countries.


This Substack is reader-supported. To receive new posts and support my work, consider becoming a free or paid subscriber.



Read the whole story
alvinashcraft
2 hours ago
reply
Pennsylvania, USA
Share this story
Delete

Migrating EWS notifications to Microsoft Graph

1 Share

Migrating from the Exchange Web Services (EWS) notification framework, which supports push, pull, and streaming notification types, to the Microsoft Graph subscription model represents a transition toward a unified, stateless, and event-driven framework. This framework supports more than just Exchange data. Although Microsoft Graph streamlines notifications through webhooks, replacing the varied EWS push, pull, and long-lived connection models requires an architectural redesign.

You can migrate your applications by integrating modern Microsoft Graph capabilities like rich notifications for reduced latency and immutable IDs for stable item tracking. A successful migration involves moving beyond simple event listening to a hybrid strategy that combines near-real-time change notifications with delta queries for reconciliation, while navigating the strict concurrency and availability thresholds of a cloud-native environment. 

EWS notifications 

An application can use three types of EWS notifications, each with different tradeoffs in terms of latency, scalability, and connection management: 

  • Push notificationsExchange sends an HTTP/HTTPS request to a listener endpoint hosted by your application whenever an event occurs. 
  • Pull notificationsThe application periodically calls Exchange to check for new events. 
  • Streaming notificationsEstablishes a long-lived connection to Exchange (via an HTTP get), allowing the server to push events down to the client as they occur. This eliminates the need for a public endpoint. 

Microsoft Graph change notifications 

Microsoft Graph only has one type of change notification, which is delivered via webhooks—HTTP POST requests sent to a listener endpoint hosted by your application when a subscribed event occurs. This model enables near real-time updates without the need for constant polling. 

For more advanced scenarios, Microsoft Graph also supports delivering change notifications through Azure Event Hubs. This option is better suited to enterprise-grade applications, and provides enhanced security, scalability, and reliability, particularly in high-throughput or distributed processing environments. 

Microsoft Graph rich notifications 

Microsoft Graph rich notifications allow change notifications to include relevant data about the item that triggered the event. For real-time notification scenarios, this data inclusion reduces latency between when an item arrives and when the client is notified, and provides immediate access to key details (such as the subject of a new message and who the sender was). 

Rich notifications simplify certain use cases compared to traditional EWS notifications. For applications where real-time notification is the primary requirement, rich notifications reduce the need for follow-up calls to retrieve item data. 

Pull notifications and change tracking in Microsoft Graph 

In EWS, notifications relied on the GetEvents operation to retrieve the changes since the last notification. In push and pull notifications, a watermark was available that acted as a subscription marker. In Microsoft Graph, the equivalent capability is provided through delta queries. 

Delta queries enable applications to track changes by requesting only the data that has been added, updated, or deleted since the previous query. Instead of maintaining a connection or polling for events, applications store a delta token returned by Microsoft Graph and use it in subsequent requests to continue where they left off. 

Microsoft Graph supports delta queries for the following resource types: 

  • Folders: Individual Mail, Contact, and Calendar folders. 
  • Item collections: Messages, contacts, events, and to do (tasks). 

For calendar data, delta queries are supported on both event collections that expose unexpanded recurrence data (where a recurring series is represented as a single master event) and calendar views that return expanded instances of those recurrences (where each occurrence is expanded as an individual event within a specified time range).

Immutable IDs 

Microsoft Graph introduces immutable IDs for mailbox items, a capability that has no direct equivalent in EWS. An immutable ID is a stable, unique identifier for an item — such as a message, contact, or event — that remains constant for the lifetime of the item within a mailbox. 

Unlike EWS and Microsoft Graph itemId values, which change when an item is moved between folders, an immutable ID remains unchanged. This means that if an application stores the ID externally, it continues to reference the same item regardless of folder moves within the mailbox. 

Immutable IDs simplify application design compared to EWS. With EWS, developers often needed to track and update externally stored item identifiers after item move operations — a common use case for notifications. With immutable IDs, that additional tracking logic is unnecessary. As a result, the code is more robust and easier to maintain. 

Note that when items move across mailbox boundaries — such as between mailboxes or from a mailbox to an archive store — the immutable ID is invalid because the item is assigned a new ID. If your application needs to track items moved between a mailbox and an archive, consider using a custom extended property instead.

Differences in subscriptions between EWS and Microsoft Graph 

In EWS, subscriptions are typically created against a specific mailbox folder or across all folders within a mailbox. 

In Microsoft Graph, change notification subscriptions can be created on specific folder types (such as Inbox or Calendar) or on resource collections such as `messages`, `contacts`, or `events`. However, this model is more constrained than EWS. It supports a reduced set of folder types and doesn’t provide the same level of granularity across all mailbox folders. 

For example, consider an EWS application that uses EWS notifications to subscribe to all mail folders in a mailbox. The application needs to detect when a new email arrives, as well as when an email is moved into a processed folder. With Microsoft Graph, the application instead subscribes to the /messages collection to receive notifications for the entire mailbox. 

To track moves, the application monitors created and deleted events and checks the parentFolderId to determine the item’s location. Because standard item IDs change when a message moves between folders, the application uses immutable IDs to correlate the item’s identity across the mailbox. The application then uses delta queries to reconcile these changes, allowing it to distinguish between newly received messages and moved messages. 

Custom folders gap 

Microsoft Graph subscriptions don’t work for all mailbox folders. Custom folders or folders that are typically associated with legacy client features aren’t accessible through the Microsoft Graph messages, contacts, events, or to do endpoints. For custom folders, you can either find an alternative solution outside of Exchange or migrate content to a supported endpoint such as messages, where webhooks are available. 

Streaming subscription gap 

Because Microsoft Graph doesn’t provide an equivalent to the EWS streaming subscription model, applications that use streaming notifications typically require architectural redesign. Instead of maintaining long-lived connections, Microsoft Graph relies on webhook-based notifications, which require a publicly accessible endpoint. 

A common approach is to host the application on a highly available platform that can expose a secure public endpoint, such as Microsoft Azure or a comparable cloud provider. This hosting ensures reliability, scalability, and proper handling of incoming notifications. For any device-based notification (such as mobile or desktop) applications, you can use a backend processing layer that forwards a simplified notification to a mobile push service, such as: 

  • Apple Push Notification service (APNs) for iOS 
  • Firebase Cloud Messaging (FCM) for Android 

For higher-volume or enterprise scenarios, Azure Event Hubs provides a more scalable and resilient pattern to ingest and process large numbers of notifications. 

Moving away from streaming subscriptions also reduces the security and operational risks associated with maintaining persistent connections. This approach results in a more robust and cloud-aligned architecture. 

Differences in event types 

EWS provides more granular event types than Microsoft Graph. Consider this difference during migration. 

Item creation and new email arrival 

  • EWS: NewMail (specific to Inbox) or Created (other folders). 
  • Microsoft Graph: Created (Unified for messages, contacts, and events). 

Microsoft Graph doesn’t expose a dedicated NewMail event—new items are surfaced simply as created. This means a created event can represent either a newly delivered email or an item that has been copied or moved into a folder. 

If your application relies on NewMail-specific behavior, you need to infer this distinction by using message properties such as receivedDateTime and createdDateTime to determine whether the message was delivered or just moved or copied. 

✏ Modifications and updates 

  • EWS: Modified 
  • Microsoft Graph: Updated 

These operations are functionally identical. 

🗑 Deletions and lifecycle 

  • EWS: DeletedMovedCopied 
  • Microsoft Graph: Deleted 

Microsoft Graph doesn’t expose explicit moved or copied event types. In scenarios where distinguishing between these actions is important, applications need to infer intent by correlating events across folders and using the immutableId. 

For example, when a message is moved from the Inbox to a custom folder, Microsoft Graph emits a delete event in the Inbox and a create event in the destination folder. Because the immutableId remains the same, these two events can be correlated to identify the operation as a move. 

In contrast, a copy operation results in a create event in the destination folder with a new immutableId, and no corresponding delete event in the source folder. 

This represents a shift from EWS, where move and copy operations were explicitly surfaced. With Microsoft Graph, developers must adopt a more interpretive approach, using event patterns and identifiers to determine the underlying action. 

Tips 

When working with subscriptions, the clientState value is only returned when you retrieve a specific subscription by using a GET request. It isn’t included when you enumerate subscriptions. In this case, the clientState property is always null.

Throttling 

EWS and Microsoft Graph use different throttling models, and subscriptions are one area where these differences are important. In Microsoft Graph, Exchange enforces a strict limit of four concurrent connections per mailbox. This limit applies across all active requests, including those triggered by subscription processing. If your application processes large items or handles a high volume of events, it can exceed this limit and throttling can occur. 

A common pitfall is treating each notification as an independent unit of work and creating parallel requests to process it. Under load, this can result in exceeding the concurrent connection limit, increased latency, and repeated throttling, which in turn slows overall throughput rather than improving it. 

To operate efficiently within these constraints, adopt a more controlled processing model. Queue incoming events and process them in a managed pipeline rather than in parallel bursts. Implement deduplication logic to coalesce closely spaced events — such as multiple create or update notifications for the same item — to avoid redundant work. 

In addition, enforce client-side concurrency controls (for example, using a bounded worker pool or semaphore) to ensure that no more than four concurrent requests are made against a mailbox at any given time. To further improve resilience and throughput, incorporate retry logic with backoff, and prioritize lightweight operations (such as delta queries) over repeated full item retrievals. 

Performance and throttling thresholds for webhook endpoints 

Another key difference between Microsoft Graph webhooks and EWS push notifications is how performance and availability of the notification endpoint are enforced. Microsoft Graph actively monitors your webhook responsiveness and applies back-pressure when thresholds are exceeded. 

slow state is triggered when more than 10% of responses take longer than 10 seconds within a 10-minute window. When this occurs, Microsoft Graph delays all new notifications by approximately 10 seconds before delivery. For real-time notification scenarios, this introduces noticeable latency and can cause notifications to fall out of sync with user expectations. 

A more severe drop state is triggered when more than 15% of responses exceed 10 seconds within the same 10-minute window. In this case, Microsoft Graph temporarily stops delivering new notifications to the endpoint for up to 10 minutes. Any notifications generated during this period aren’t replayed after the endpoint recovers, which can result in missed events. 

Microsoft Graph webhooks impose stricter performance requirements on the listening endpoint than EWS push and streaming notifications. Applications must acknowledge receipt quickly and incorporate logic for resilience and recovery. To account for missed or delayed notifications, a reconciliation process using delta queries is a necessary to maintain data consistency. 

Glen Scalesis a Microsoft MVP and senior developer specializing in Exchange, Active Directory, Office 365, and Teams. You can follow his work on his eMail Development Substack.

The post Migrating EWS notifications to Microsoft Graph appeared first on Microsoft 365 Developer Blog.

Read the whole story
alvinashcraft
2 hours ago
reply
Pennsylvania, USA
Share this story
Delete
Next Page of Stories