MICROSOFT AGENT FRAMEWORK · 0.16.0-rc.1
Demo320 — Durable Approval
After start: Waiting, zero rows. After approve: Completed, StoredItem and ItemId. After identical resume: same ItemId, exactly one row. Retain the waiting receipt to force real checkpoint replay.
Objectives
- Approve or refuse an immutable proposal and replay a unique SQLite effect.
Prepare the program
No model, embeddings, container or secret required. Start at the root of the complete distribution. Preserve shared projects and configuration files. Some historical prompts and labels in Demo260–290 remain French in public code; commands and identifiers match this revision.
dotnet build BaseTechnique.slnx -m:1 -c Release| Project | Role |
|---|---|
| demos/Demo320_DurableApproval/Demo320.App.csproj | App |
| shared/Maf.Durable/Maf.Durable.csproj | Shared implementation |
Commands from the root
$state = Join-Path $env:TEMP ('maf-demo320-' + [guid]::NewGuid().ToString('N'))dotnet run --project demos/Demo320_DurableApproval/Demo320.App.csproj -c Release --no-build -- start $statedotnet run --project demos/Demo320_DurableApproval/Demo320.App.csproj -c Release --no-build -- status $statedotnet run --project demos/Demo320_DurableApproval/Demo320.App.csproj -c Release --no-build -- resume $state approvedotnet run --project demos/Demo320_DurableApproval/Demo320.App.csproj -c Release --no-build -- resume $state approvedotnet run --project demos/Demo320_DurableApproval/Demo320.App.csproj -c Release --no-build -- status $stateProcedures and variants
Run the sequence below then the refusal/replay exercise. Each command is a separate process and must reuse the same directory.
public ApprovalState Apply(ApprovalDecision decision)
{
RecordDecision(decision);
using var connection = Open();
using var transaction = connection.BeginTransaction();
using var command = connection.CreateCommand();
command.Transaction = transaction;
command.CommandText = """
INSERT INTO ApprovedBacklogItems (OperationId,Draft,CreatedUtc)
SELECT OperationId,Draft,$utc FROM Approvals WHERE OperationId=$id AND Status IN ('Approved','Completed')
ON CONFLICT(OperationId) DO NOTHING;
UPDATE Approvals SET Status='Completed' WHERE OperationId=$id AND Status='Approved';
""";
command.Parameters.AddWithValue("$id", decision.OperationId);
command.Parameters.AddWithValue("$utc", DateTimeOffset.UtcNow.ToString("O"));
command.ExecuteNonQuery();
transaction.Commit();
return Read(decision.OperationId);
What must be observable
After start: Waiting, zero rows. After approve: Completed, StoredItem and ItemId. After identical resume: same ItemId, exactly one row. Retain the waiting receipt to force real checkpoint replay.
These results are expected from the linked code. Checks actually rerun for this lot are distinguished in exercises and reception; no unmeasured live output is presented as observed.
Limits and retained state
Demo300 responds in the live process; Demo310 retains its manager in memory; only Demo320 stores file checkpoints for another-process recovery. SQLite exists in all three variants. Local row uniqueness, no distributed exactly-once. The CLI trusts its operator without reviewer authentication.
dotnet test tests/Maf.Durable.Tests/Maf.Durable.Tests.csproj -m:1 -c Release --no-build --no-restore