Who owns an AI agent after it goes live?

Ownership, held in hand

Governing AI Agents in Practice — Article 01

An AI agent has gone live. People are using it, the project team has moved on, and someone reports that it has given the wrong advice.

Who picks that up?

The person who built it might investigate. IT might check whether the service is running. The business team might correct the answer. But who decides whether the agent should keep operating while the problem is understood?

That is the ownership question I would settle before launch.

Separate the responsibilities

My starting recommendation is to name a business or product owner who is answerable for the agent’s purpose, outcomes and results. That person should understand what useful performance looks like, prioritise improvements and secure funding for its continued operation.

A product owner taking this role needs the authority to make those business decisions. Recording a name is only useful if the person understands and accepts the accountability.

This does not mean asking that owner to troubleshoot integrations or approve security exceptions. Those responsibilities need their own owners and authority.

Technical maintenance covers the agent’s configuration, connections, testing and releases. It also requires a working relationship with whoever owns the information the agent uses. A technically healthy agent can still give an unsuitable answer when its source material is outdated or contradictory.

Operational support covers what happens when someone needs help: receiving reports, assessing impact, involving the right specialists and coordinating recovery.

Depending indefinitely on the original maker is fragile. People change teams, leave the organisation or take on other work. Support needs documented knowledge, appropriate access and someone who can take over.

In a smaller organisation, one person may cover several roles. The important thing is to make the responsibilities explicit and provide backup.

A hypothetical example: an expense-policy agent

Imagine a company introduces an agent in Microsoft Teams, built with Copilot Studio. Employees use it to ask about travel expenses and prepare reimbursement requests. Finance staff still approve payments.

A few weeks after launch, the company changes its hotel allowance. An employee reports that the agent is quoting the previous limit.

The service desk records the issue and routes it to the agreed support lead. Finance confirms the correct policy and assesses whether employees have relied on the wrong answer. The technical maintainer investigates whether the cause is an old document, conflicting sources or the agent’s handling of the question.

Under an agreed incident procedure, support can suspend the affected function and direct employees to Finance. The business owner coordinates the response to affected users. Finance validates corrected answers, and the technical team completes the required checks before the function returns.

Nobody needs to own every part of that response. They do need to know who makes each decision.

Now imagine the agent also approves reimbursements. Who sets approval limits, reviews disputed decisions and authorises recovery when an incorrect payment occurs? The support arrangement should reflect those consequences.

Where the CoE fits

The Centre of Excellence can establish shared policies and guide teams on ownership, testing, monitoring and escalation, working with security, risk and service management.

It can also make ownership visible through a documented record: who is accountable, who maintains the agent and where support requests should go.

The CoE needs a defined remit and enough capacity to carry it out. Making it responsible for every agent’s answers, maintenance and incidents would quickly stretch that remit beyond what it can reasonably manage.

Some organisations may initially need a central team to maintain agents because specialist skills are scarce. Even then, each agent still needs someone accountable for its business outcomes.

Make ownership usable

Before launch, I would ask the people involved to complete a short ownership record covering:

  • The accountable business or product owner, technical contact, support lead and their backups.
  • Who maintains the source knowledge and validates business correctness.
  • Who can suspend the agent, and who approves its return.
  • Support hours, escalation routes and a fallback process.
  • The review date, running-cost budget and person authorised to retire it.

Then walk through one realistic incident together. A missing decision becomes easier to spot when people explain what they would actually do.

Review that record when people leave, the agent gains new capabilities or its business purpose changes. Ownership has to remain usable after the launch meeting.

A practical test is simple: if the agent gives a harmful answer tomorrow, can the people responsible explain who will respond, who will decide and how users will keep working?


Further reading

Exception in Microsoft Teams Channel created using Power Automate / Graph API “Folder location for this channel is not ready yet, please try again later”

I was automating Teams private channel creation using Power Automate, and faced the below error when I tried to access the channel’s file location via graph API.

“Folder location for this channel is not ready yet, please try again later“

The Issue

Yes, the folder location is not automatically provisioned when a channel is created, because the SharePoint site will get created only when you hit Files tab from the UI after Channel creation.

This is by design.

Workaround

Executing the graph query /teams/{id}/channels/{id}/filesFolder on the private channel can mimic the files tab action from UI. However, it may not work on the first attempt, and will return a 404 response, you may have to try 3-5 times. So we need to use a catch for first attempt and then loop it until the the graph call succeeds. Please see the bow image for reference.

You can find the documentation for filesFolder request here. This issue exist for standard channels (Non-Private) as well. However, for standard channels, you only need to call the filesFolder request only once.

Hope this helps!!!

I Wish I Would Have Known #31: App Access Checker

App access checker image

You can enter a user’s email address and see the list of published apps in your environment and all the access, license, and security information specific to that user. This can be very useful in troubleshooting why a user cannot see a specific app in your environment. The tool can be accessed from the admin center or via direct URL.

https://<org>.crm.dynamics.com/WebResources/msdyn_AppAccessChecker.html 

Hope this helps..

Early Bound vs Late Bound Programming in Dataverse

image of a computer screen with programming code

As you all know, when working with code for Microsoft Dataverse we have two options late-bound and early-bound. I have seen many people advocating one option over another and explaining why one is better than the other. For me, it’s just a personal choice, if you prefer typed classes go for early bound else go for the late-bound approach. Add some additional details below to help you to select a programming option.

Early Bound

Early-bound programming requires that you first generate a set of classes based on the table and column definitions (entity and attribute schema) for a specific environment using the code generation tool. Once generated you can enjoy better IntelliSense and compile-time checking of all types so that no implicit casts occur. Below is the sample early bind code from Microsoft Docs which creates an account record.

var account = new Account();
// set attribute values
    // string primary name
    account.Name = "Contoso";
    // Boolean (Two option)
    account.CreditOnHold = false;
    // DateTime
    account.LastOnHoldTime = new DateTime(2017, 1, 1);
    // Double
    account.Address1_Latitude = 47.642311;
    account.Address1_Longitude = -122.136841;
    // Int
    account.NumberOfEmployees = 500;
    // Money
    account.Revenue = new Money(new decimal(5000000.00));
    // Picklist (Option set)
    account.AccountCategoryCode = new OptionSetValue(1); //Preferred customer

//Create the account
Guid accountid = svc.Create(account);

Late Bound

Here you don’t need to generate the classes, you directly start wrting your logic, However, you need to refer to tables and columns (entities and attributes) using their LogicalNames in the Entity class. You don’t get compile-time validation on names of entities, attributes, and relationships. Types are checked only when the object is created. Below is the sample late bind code from Microsoft Docs which creates an account record.

//Use Entity class specifying the entity logical name
var account = new Entity("account");

// set attribute values
    // string primary name
    account["name"] = "Contoso";            
    // Boolean (Two option)
    account["creditonhold"] = false;
    // DateTime
    account["lastonholdtime"] = new DateTime(2017, 1, 1);
    // Double
    account["address1_latitude"] = 47.642311;
    account["address1_longitude"] = -122.136841;
    // Int
    account["numberofemployees"] = 500;
    // Money
    account["revenue"] = new Money(new decimal(5000000.00));
    // Picklist (Option set)
    account["accountcategorycode"] = new OptionSetValue(1); //Preferred customer
                
//Create the account
Guid accountid = svc.Create(account);

Now let’s do a comparison on both.

Early-boundLate-bound
You can verify entity, attribute, and relationship names at compile timeNo compile-time verification of entity, attribute, and relationship names
You must generate entity classesYou don’t need to generate entity classes
Better IntelliSense supportLess IntelliSense support
Less readable codeMore readable code
Slightly less performantSlightly more performant
Generated classes are quite largeGenerated classes are small

Hope this helps.

Event Execution Pipeline in Dataverse/Dynamics 365

When the standard low-code options cannot handle your business logic in an expected manner, as a developer, you can use custom event handlers in Microsoft Dataverse. The Event Framework provides the capability to register custom code to be run in response to specific events.

The custom code options available are Plugins, Azure integrations, virtual table data providers, and Webhooks, etc… When configured correctly using the plugin registration tool, these custom code extensions will respond to events that are provided by the event framework.

When an event occurs a message is sent to the organization Web service to process the event. The message contains information about the event, such as details of the table where the event occurred, dataverse organization details, details of the user who triggered the event, etc… There is a specific message for each event such as create, update, retrieve, retrieve multiple, associate, disassociate, delete, etc… Each message is processed in a series of 4 stages called the event execution pipeline and your custom code extension can be registered at any of these stages based on your business need. See the below table for the details about each stage.

Stage NameDescription
PreValidationThis stage will occur before the main system operation. This provides an opportunity to include logic to cancel the operation before the database transaction.
This stage occurs before any security checks are performed to verify that the calling or logged-on user has the correct permission to perform the intended operation.
PreOperationOccurs before the main system operation and within the database transaction. If you want to change any values for an entity included in the message, you should do it here.

Avoid canceling an operation here. Canceling will trigger a rollback of the transaction and have a significant performance impact.
MainOperationFor internal use only except for Custom API and Custom virtual table data providers.
More information:
Create and use Custom APIs
Custom Virtual table data providers
PostOperationOccurs after the main system operation and within the database transaction. Use this stage to modify any properties of the message before it is returned to the caller.

Avoid applying changes to an entity included in the message because this will trigger a new Update event.

Within the PostOperation stage, you can register steps to use the asynchronous execution mode. These steps will run outside of the database transaction using the asynchronous service. More information Asynchronous service.

Hope this helps.