MICROSOFT AGENT FRAMEWORK · 0.16.0-rc.1
Business journal and effect evidence
Distinguish intention, acknowledgement and committed effect; reopen the database to verify local evidence.
Objectives
- Persistent journal and effect readback
- Correlation after restart
- Difference from a continuous distributed trace
Start with the effect to prove
“The request was recorded” is a claim to verify. A call trace and read acknowledgement do not prove a write. The business journal stores a minimal chronology of host events; RecordedDecisions stores the local ReviewRequested action. Evidence means linking the commit event to that row read back from storage.
- Host GUID → RequestReceived → accepted workflow
- Intention → SQLite transaction
- RecordedDecisions + ActionCommitted → same commit
- New process → Read → HasAction
Choose events and meanings
| Mechanism | Scope |
|---|---|
| RequestReceived / Intention | Request received / intended action; no proven write |
| Acknowledged | Read tool called; no business effect |
| ActionCommitted + ActionId | Created by CommitReview with the business row |
| ExecutionSucceeded / Failed / Cancelled | Scenario outcome; later failure does not undo an earlier commit |
JournalEntry accepts only a host GUID, UTC timestamp, current TraceId, closed enum and optional ActionId. It contains no functional user, conversation, tool arguments/results or free exception text. The old script proposed more data; the renovated program chooses this minimal shape to avoid storing secrets as supposed evidence. It does not reveal internal model reasoning.
Guarantee atomicity in this database
public long CommitReview(Guid executionId)
{
using var connection = Open();
using var transaction = connection.BeginTransaction();
using var command = connection.CreateCommand();
command.Transaction = transaction;
command.CommandText = "INSERT INTO RecordedDecisions(ExecutionId,Decision) VALUES($id,'ReviewRequested') ON CONFLICT DO NOTHING";
command.Parameters.AddWithValue("$id", executionId.ToString("N"));
bool created = command.ExecuteNonQuery() == 1;
command.CommandText = "SELECT Id FROM RecordedDecisions WHERE ExecutionId=$id";
long id = (long)command.ExecuteScalar()!;
if (created) Insert(connection, transaction, executionId, JournalKind.ActionCommitted, id);
transaction.Commit();
return id;
Source code · Maf.Observability · Folder
CommitReview opens a transaction, inserts under unique ExecutionId, reads the identifier, creates ActionCommitted only for a new row, then commits. Repeating the same GUID returns the same action without a second event. Append forbids ActionCommitted: an intention or generated text cannot manufacture commit evidence through that API.
Correlation relates observations; atomicity binds two writes to the same transaction. They are different guarantees. This transaction covers no remote system. For human approval and durable resumption, return to Demo320; the journal replaces neither host permission nor binding to the approved proposal.
Read back after restart
public bool HasAction(Guid executionId, long actionId)
{
using var connection = Open();
using var command = connection.CreateCommand();
command.CommandText = "SELECT COUNT(*) FROM RecordedDecisions WHERE ExecutionId=$id AND Id=$action";
command.Parameters.AddWithValue("$id", executionId.ToString("N"));
command.Parameters.AddWithValue("$action", actionId);
return (long)command.ExecuteScalar()! == 1;
Source code · Maf.Observability · Folder
if (Value(args, "--read") is string read)
{
var entries = journal.Read(Guid.Parse(read));
Console.WriteLine(JsonSerializer.Serialize(entries));
return entries.Count > 0 && entries.Where(e => e.Kind == JournalKind.ActionCommitted)
.All(e => e.ActionId.HasValue && journal.HasAction(e.ExecutionId, e.ActionId.Value)) ? 0 : 1;
Source code · Maf.Observability · Folder
Retain Database and ExecutionId, end the process, then call --read with the same file. Read orders by Id and preserves the original TraceId. HasAction checks RecordedDecisions for that GUID and ActionId. Record the exit code and also inspect Kind: --read can succeed for a nonempty failed chronology without ActionCommitted because its commit check then has no rows. Exit 0 therefore does not mean “action performed”.
Retention and scope of evidence
At each new execution, code policy purges metadata older than 30 days; read-only inspection does not trigger that purge. --erase deletes an execution’s metadata without undoing its action. Business-row retention is separate. SQLite performs logical deletion; free pages, copies and backups may remain. Protect files and output through operating-system permissions.
The journal is mutable, unsigned and offers no append-only or tamper-evidence guarantee. The teaching database is separate from preserved historical EP008 databases. Reading back a TraceId does not revive an active span or a continuous distributed trace. No global exactly-once, remote effect or regulatory compliance is demonstrated.
Observe success and failure
Prerequisites
Continue reading
Previous
Next
