> ## Content Index
> Fetch the complete content index at: https://devinside.cloud/llms.txt
> Use this file to discover other available public pages before exploring further.

# An Agent Cost Ledger in .NET: Attempts, Quality and Successful Tasks
- URL: https://devinside.cloud/an-agent-cost-ledger-in-net-attempts-quality-and-successful-tasks/
- Published: 2025-06-03T12:45:00.000Z
- Updated: 2026-11-12T17:08:22.000Z
- Description: A runnable synthetic ledger preserves attempt identity, corrections and unknown usage, then refuses a precise cost-per-accepted-task ratio when the observed history is incomplete.
- Author: Marcin Borecki
- Tags: Engineering, Performance & Runtime, #ai01, #devinside-review

START WITH THE MECHANISM

Interactive companion and laboratory update: 12 November 2026\. The editorial date places the topic on the timeline; this current explanation and its measured evidence retain their actual preparation and execution dates.

THE FULL INVESTIGATION

## An Agent Cost Ledger in .NET: Attempts, Quality and Successful Tasks

Editorial context: 3 June 2025 · Prepared and updated: 12 November 2026

Dates and technology context

This is a retrospective editorial timeline. Topic context: 3 June 2025\. First publicly available: 12 November 2026\. Current text, visuals and laboratory revisions were prepared on 12 November 2026.

Executed .NET10.0.15 ledger, 1,461 checks,720 permutations, synthetic trace and timing are the12Nov2026 implementation update.

An agent returns an answer. The final model call has a usage record, the answer passes a review, and a dashboard divides its cost by one successful request. The number looks precise. It may also omit the failed attempt, the tool call and the usage observation that has not arrived yet.

The problem is not arithmetic first. It is identity and evidence. What counts as one task? Which attempts belong to it? Is a repeated event a second charge or another delivery of the same observation? Does an absent usage field mean zero work, or work whose quantity remains unknown? Which version of a later correction should the report use?

A useful cost ledger has to answer those questions before dividing anything. Otherwise a cheaper-looking configuration can simply be the configuration that loses more of its history.

This article implements a small C# ledger with versioned observations, duplicate detection, explicit unknown usage and an accepted-task denominator. The laboratory compiled and passed 1,461 checks on .NET 10.0.15 using SDK 10.0.400\. Its tests include all 720 arrival orders of a six-event fixture, repeated imports, incomplete histories and arithmetic overflow. An independent batch oracle uses a different aggregation route and arbitrary-precision arithmetic.

All quantities, rates and acceptance labels in this laboratory are synthetic. No provider billing, account balance, budget, quota or live model was queried. The measured experiment concerns replaying ledger records and producing a snapshot. It is not a model-quality benchmark, a real tariff comparison or a claim that one agent is cheaper than another.

## Start with identities that survive retries

The task is the unit the user wanted completed. An attempt is one piece of work performed in pursuit of that task. A revision is a new observation about the same attempt. These identities must remain distinct even when their timestamps are close together.

Suppose task A asks for a grounded answer. Attempt a invokes a model; attempt b calls a tool. The model usage arrives first as unknown and later as a known quantity. Those are two revisions of attempt a, not two model attempts. If the second revision is delivered twice, it is still one observation and must not increase the total.

A real retry is different. It receives a different attempt identity because additional work happened. Deduplicating every observation with the same task identity would erase retries. Counting every delivered observation as a new attempt would invent them. Both errors can make the arithmetic look plausible while violating the operation being described.

The example does not implement a provider adapter. Its input is an already normalized record. That is deliberate: a provider's request identifier, a transport retry identifier and the application's task identifier may have different meanings. An adapter must establish those meanings from the actual API contract rather than rename one field and assume equivalence.

The acceptance decision also has its own versioned slot. It says whether the task outcome was accepted under the fixture's rubric and lists the attempt identities that should exist. Acceptance is not inferred from an HTTP status, a model returning text or the presence of a cost record. The laboratory treats it as a supplied decision whose relationship to usage must be checked.

In a real evaluation, the rubric and reviewer would require their own evidence. Here they are fixed synthetic labels. That lets us test whether the ledger faithfully preserves a decision without pretending that it independently knows whether an answer is useful.

## Use an explicit unknown, not a convenient zero

03 / A concrete example

### Zero, unknown and absent are different

![A known zero quantity, an unknown quantity and a missing expected attempt produce different completeness states.](https://devinside.cloud/content/images/2026/11/devinside/AI01-v3.svg)

[Enlarge diagram](https://devinside.cloud/content/images/2026/11/devinside/AI01-v3.svg)

All three situations can leave the known subtotal unchanged. Only an explicitly observed zero supplies the evidence needed to treat that attempt as a known zero-cost contribution.

Interpretation and evidence
- Null quantity is not zero.
- An absent expected attempt is a history gap.
- Show missingness beside the subtotal.
synthetic conceptual explanation matching tested contract

The record shape is intentionally small. The same immutable record type represents a usage observation or a task decision, with validation separating the two shapes:

```csharp
public sealed record Entry(
    string TaskId,
    string Slot,
    int Revision,
    long? Quantity,
    string RateKey,
    bool Finished,
    string? Manifest,
    bool? Accepted);

```

For usage, `Slot` is the attempt identity. `Quantity` is nullable. A null value means that the ledger does not know the quantity; zero means that an observation explicitly reported zero. `Finished` separately indicates whether the attempt is terminal. A quantity can be known while the attempt remains open, so these are not interchangeable fields.

For a decision, the reserved slot is `$decision`. Its manifest is a canonical list of expected attempt identities, and its acceptance field is required. Usage fields must be absent. The constructor helpers make valid records convenient, while the append boundary rejects invalid shapes, nonpositive revisions, negative quantities and unknown rate keys.

The use of one compact record is a fixture choice. A larger system may prefer separate discriminated event types and explicit schema versions. The important property is that validation prevents ambiguous states, rather than allowing a record to mean whichever interpretation makes a query easiest.

Consider two records: a completed attempt with quantity zero, and a completed attempt with quantity null. Both contribute zero to the currently known subtotal. Only the first permits a complete total. If the final report renders both as a zero-cost attempt, it turns missing evidence into a claimed measurement.

This distinction must survive serialization. The example exports the original events and the snapshots after each append to JSON. A downstream reader must preserve nulls rather than coerce them into numeric defaults. The included round-trip test imports serialized records and verifies that the snapshot remains the same.

The manifest serves a different missingness check. If the decision expects attempts a and b but only a is present, the history is incomplete even when a has perfectly known usage. If a different attempt c appears instead of b, the counts can match while the identities do not. The ledger compares sets, not just counts.

## Treat revisions as replacement observations

02 / Watch the mechanism

### A late revision is not another attempt

![Revision two arrives before revision one, then revision two repeats; the current value stays at revision two and duplicate delivery does not add cost.](https://devinside.cloud/content/images/2026/11/devinside/AI01-v2.svg)

A late revision is not another attemptRevision two arrives before revision one, then revision two repeats; the current value stays at revision two and duplicate delivery does not add cost.AI01 / MOTIONA late revision is not another attemptA/a revision 2quantity 2A/a revision 1quantity unknownA/a revision 2quantity 2Current: revision 2Charge: 6 synthetic unitsDuplicate delivery does not add another chargeSynthetic accounting units. No real tariff or model result.

Play animation[Enlarge diagram](https://devinside.cloud/content/images/2026/11/devinside/AI01-v2.svg)

Static view. Play to see how the mechanism unfolds.

The current view selects the highest revision, not the latest arrival. Keeping old revision identities also lets the ledger reject a conflicting copy of an earlier observation.

Interpretation and evidence
- Order revisions by their declared version.
- Ignore identical redelivery.
- Reject conflicting content for one revision.
synthetic conceptual explanation matching tested contract

The append algorithm stores two views: every distinct revision seen, and the highest revision for each task-and-slot pair. The first detects conflicting deliveries. The second determines the current report.

```csharp
public void Append(Entry entry)
{
    Validate(entry);
    var version = (entry.TaskId, entry.Slot, entry.Revision);
    if (history.TryGetValue(version, out Entry? prior))
    {
        if (prior != entry)
            throw new InvalidDataException("Conflicting duplicate revision.");
        return;
    }

    history.Add(version, entry);
    var key = (entry.TaskId, entry.Slot);
    if (!current.TryGetValue(key, out Entry? latest)
        || entry.Revision > latest.Revision)
        current[key] = entry;
}

```

Arrival order is not the correction policy. Revision 2 remains current if revision 1 arrives afterward. Two identical copies of revision 2 are idempotent. Two different values claiming to be revision 2 are a conflict and are rejected. The system does not choose whichever payload arrived last and quietly overwrite the other.

Keeping old revisions matters. Suppose revision 2 has already replaced revision 1, and a conflicting copy of revision 1 arrives later. A system storing only the latest revision might ignore the conflict as irrelevant old data. This fixture still detects it because the history dictionary preserves the earlier identity-to-content relationship.

This is not a tamper-proof audit system. It is a single-threaded in-memory replay implementation. There is no concurrent database transaction, durable append protocol or authenticated producer identity. A production implementation would need to preserve the same uniqueness and conflict rules at a storage boundary appropriate to its writers.

The API choice alone does not establish idempotency. For example, a dictionary's add-if-absent operation can decline an existing key without comparing the value. The application still needs a policy for identical and conflicting content. [Dictionary.TryAdd documentation](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.tryadd?view=net-10.0&ref=devinside.cloud).

Revisions are supplied by the fixture producer and must be positive. The ledger does not solve distributed revision allocation. If several independent writers can correct the same attempt, they need a shared ordering or conflict-resolution contract. A random timestamp is not automatically an adequate replacement, especially when clocks disagree.

## Keep the price card synthetic and fixed

The laboratory uses a tiny versioned price card named `synthetic-v1`. A unit under the key `model` costs three synthetic accounting units, and a unit under `tool` costs five. These names classify fixture operations; they are not prices per token or claims about an actual vendor.

```csharp
public static class SyntheticPriceCard
{
    public const string Version = "synthetic-v1";

    public static long Rate(string key) => key switch
    {
        "model" => 3,
        "tool" => 5,
        _ => throw new InvalidDataException("Unknown synthetic rate.")
    };
}

```

The values are deliberately simple enough to check by hand. The purpose is to test multiplication, revisions and the reporting boundary, not to imitate a complicated invoice. Unknown rate keys are rejected so a missing entry cannot silently become a free operation.

One replay uses one fixed price-card version. The exported example includes that version and its values. Supporting several historical tariffs would require a per-observation rate-version relationship or another explicit selection rule. This implementation does not infer a tariff from arrival time, and it does not claim to support retroactive repricing across multiple real contracts.

Quantities and synthetic rates are integral. The multiplication and subtotal are checked operations:

```csharp
units = checked(
    units + checked(quantity * SyntheticPriceCard.Rate(usage.RateKey)));

```

Overflow is a failed report, not a wrapped total. In a checked arithmetic context, an integral operation that cannot be represented throws rather than silently discarding high-order bits. [C# checked and unchecked arithmetic](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/statements/checked-and-unchecked?ref=devinside.cloud).

This design avoids floating-point rounding in the fixture's base unit. It does not eliminate the need for rounding policy in a real billing domain. Discounts, minimum charges, currency conversion and provider reconciliation are outside the experiment. A real adapter would need documented rules and separate tests for those operations.

The ratio uses decimal arithmetic after the integral total is established. Its unit is synthetic accounting units per accepted task. Naming the unit prevents a graph from acquiring the appearance of currency simply because its values contain decimal places.

## Calculate completeness before the denominator

01 / See the idea

### All observed costs, accepted-task denominator

![Accepted task A contributes six units and rejected task B contributes three; all nine units are divided by one accepted task.](https://devinside.cloud/content/images/2026/11/devinside/AI01-v1.svg)

[Enlarge diagram](https://devinside.cloud/content/images/2026/11/devinside/AI01-v1.svg)

In the synthetic example, task A costs six units and is accepted; task B costs three and is rejected. The workload cost is nine units per accepted task, because rejected work does not disappear from the numerator.

Interpretation and evidence
- Count a task once.
- Keep rejected-task work in the numerator.
- Acceptance is a supplied fixture label.
synthetic conceptual explanation matching tested contract

The snapshot reports the known subtotal and the reasons an exact ratio may be unavailable. It does not hide those reasons inside one success boolean:

```csharp
public readonly record struct Snapshot(
    long KnownUnits,
    int AcceptedTasks,
    int Tasks,
    int Attempts,
    int UnknownUsage,
    int OpenAttempts,
    int IncompleteHistories,
    decimal? UnitsPerAcceptedTask);

```

For each observed task, the ledger selects the current decision and current usage revision for each attempt. It counts accepted tasks once, adds known usage from all attempts and compares the observed attempt set with the decision manifest. Unknown quantity, open attempts and missing or mismatched history each prevent the ratio from being presented as complete.

The rule at the end is short:

```csharp
bool complete = unknown == 0 && open == 0 && incomplete == 0;
decimal? ratio = complete && accepted > 0
    ? (decimal)units / accepted
    : null;

```

The numerator includes work for rejected tasks. Dividing only the costs of accepted tasks by accepted tasks answers a narrower question and can conceal failed work required by the configuration. In this ledger, all observed task costs belong to the evaluated workload, while acceptance defines the useful-outcome denominator.

That does not mean every rejected task is a defect. A correct abstention can be appropriate behavior while leaving the user's wider business objective unresolved. This fixture's boolean acceptance is intentionally simple. A real evaluation may need separate categories for useful answers, justified refusals, escalations and harmful outputs, with a declared rule for which count toward its chosen outcome.

A zero denominator does not become zero cost. If work occurred but no task was accepted, the ratio is undefined under this measure. The report retains the known total and task counts, leaving the ratio null. A chart should not turn that null into a reassuring point at the origin.

There is a larger completeness boundary too. This ledger knows only tasks represented in its input. If an entire task disappears with every associated record, no event manifest inside that absent task can reveal it. A closed workload needs an independent roster of expected tasks and a rule saying when the batch is sealed. Without that roster, the ratio is conditional on the observed task set, not proof that every task in an external system was accounted for.

This limitation is deliberate and visible. It is better to state it than to name a field `Complete` and imply that completeness extends beyond the evidence available to the program.

## Walk one trace all the way to the report

04 / A concrete example

### The actual synthetic trace, step by step

![Seven generated trace snapshots show subtotal zero, then six, then nine; the ratio is unavailable while history is incomplete.](https://devinside.cloud/content/images/2026/11/devinside/AI01-v4.svg)

[Enlarge diagram](https://devinside.cloud/content/images/2026/11/devinside/AI01-v4.svg)

This table is generated from example/trace.json, not typed as an assumed result. When task B first appears, its missing decision makes the conditional ratio unavailable until the last event supplies that decision.

Interpretation and evidence
- Inspect each append, not only the final sum.
- A duplicate keeps the snapshot unchanged.
- A newly observed task can reopen incompleteness.
executed synthetic trace; example/trace.json

The generated example contains two tasks. Task A is accepted and declares attempts a and b. Task B is rejected and declares attempt c. Attempt a eventually reports quantity two under the model rate; b reports an explicit zero under the tool rate; c reports quantity one under the model rate.

The hand calculation is therefore six units for a, zero for b and three for c: nine synthetic units across one accepted task. The final ratio is nine. Counting only task A would incorrectly produce six for this workload boundary. Counting both tasks as accepted would incorrectly divide by two.

The events intentionally arrive in a less convenient order. A's decision arrives before its usage. The zero-cost tool observation arrives next. The model attempt first appears with unknown quantity and an open status. A later revision supplies quantity two and marks it finished. That revision then arrives again unchanged.

At each step, `example/trace.json` records the appended entry and the resulting snapshot. The early decision does not make the history complete. The explicit zero does not fill the missing model observation. The later known revision resolves the model's unknown state. The duplicate does not increase the subtotal.

Task B's usage then arrives before its decision. At that moment the observed task set has expanded and its completeness is unresolved. The report must not cling to the earlier ratio as though it were a final sealed-batch result. Once B's decision arrives, all declared attempts are present and finished, and the nine-unit ratio becomes available for this complete example input.

That temporary change is instructive. A revision-aware ledger is not necessarily monotonic in every displayed field. A new task can make a previously available conditional ratio unavailable. A corrected quantity can decrease a subtotal. A revised acceptance decision can change the denominator. Consumers need a snapshot identity and scope, not an assumption that every number only grows.

The accompanying `events.json` can be replayed, and `summary.csv` exposes the final fields. These are local output artifacts. They are not a transactional event store, and writing a JSON file is not proof of crash-safe persistence. The reference separates replay semantics from storage durability so each can be investigated honestly.

## Make incomplete history fail visibly

One of the most useful counterexamples has no arithmetic error. The decision lists attempts a and b, but only a is present with a known quantity. Summing available values is easy. Calling that sum the complete task cost is unsupported.

The fixture marks the history incomplete and suppresses the ratio. A second counterexample supplies a and c when the manifest expects a and b. The count is correct; the identity set is wrong. This catches a form of accidental correlation that a simple expected-count check would miss.

An open attempt is another distinct state. It can already have observed usage while remaining capable of more work. The ledger preserves that known subtotal but does not present the workload as settled. Replacing its quantity with zero because it has not finished would discard evidence, while treating its current quantity as final would overstate certainty.

Conflicting revisions fail at append. Negative quantities and unknown rate keys fail validation. Arithmetic overflow fails when producing the snapshot. These failures are not converted into a cheaper result. The laboratory expects each relevant exception and verifies that a conflicting duplicate does not append another history record.

A production ingestion service would also need a quarantine and recovery policy. The current implementation throws to make the conflict unambiguous; it does not choose whether to reject an entire upload, retain an error record or ask a producer to correct it. Those decisions depend on the durability and operational contract around the ledger.

The same principle applies to unavailable usage from a provider. A real adapter should say what it observed and preserve a reason when it cannot establish a quantity. It should not invent an estimate inside the field that otherwise means measured usage. If estimation is useful, give it a separate type and keep its assumptions visible to the report consumer.

## Use a different route to the expected answer

The tests do more than compare two runs of the append method. The small fixture has a hand-calculated expected snapshot: nine units, one accepted task, two tasks, three attempts and no unresolved completeness conditions.

Every permutation of its six entries is replayed. Six factorial gives 720 arrival orders. After each order, the same records are replayed in reverse to verify idempotence. The snapshot must remain unchanged and the unique-revision count must remain six. This directly challenges ordering and repeated-import behavior.

The independent oracle takes a batch route. It groups all records by revision identity, checks that each group has one distinct value, selects the maximum revision for each task-and-slot pair and calculates totals with `BigInteger`. That differs from incrementally maintaining a current dictionary and summing checked `long` values. `BigInteger` can represent integers beyond the fixed-width range; the oracle explicitly checks conversion back to the report's `long` range. [BigInteger documentation](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.biginteger?view=net-10.0&ref=devinside.cloud).

This independence is purposeful but bounded. Both implementations consume the same normalized event contract and the same declared synthetic rates. The oracle is not independent evidence that the contract represents a provider's billing behavior. It checks that two different aggregation approaches agree with the fixture arithmetic.

Additional tests cover missing decisions, wrong attempt identities, open attempts, unknown versus zero, zero accepted tasks, revised acceptance and conflicts in an old revision after a newer revision has arrived. Generated datasets are replayed ordered, shuffled and duplicated, then serialized and imported again.

All 1,461 checks passed in the recorded local run. That is evidence about the implemented cases, not a guarantee of all possible event streams. There is no concurrent writer test because the ledger explicitly requires a single replay owner. There is no durability test because the storage mechanism is a local fixture export rather than a database transaction log.

If concurrency or persistence is added later, those are new contracts to verify. Reusing this green count as proof of their correctness would repeat the very mistake the ledger is designed to prevent: treating available evidence as broader than it is.

## Measure the ledger mechanism, not an imaginary agent

05 / See the idea

### Keep the unstable case in the report

![All four measured replay cases show median and observed range; the thousand-task ordered case varies substantially more than the other cases.](https://devinside.cloud/content/images/2026/11/devinside/AI01-v5.svg)

[Enlarge diagram](https://devinside.cloud/content/images/2026/11/devinside/AI01-v5.svg)

Dots show median replay time, and lines show the observed range of nine samples. The large variation in the ordered thousand-task case prevents a confident claim that arrival order itself caused the timing difference.

Interpretation and evidence
- Report every configured case.
- A range is not a confidence interval.
- This measures ledger replay, not an agent.
measured; benchmark-results.json

The performance fixture generates 100-task and 1,000-task datasets. Each task contributes five delivered records: an acceptance decision, an initially unknown open model observation, a later completed revision, a tool observation and one duplicate of the completed model revision. That produces 500 or 5,000 delivered records per replay.

For each dataset size, the benchmark tests ordered input and a deterministic shuffle with seed 42\. Input records and strings are constructed before timing. Each measured replay creates a fresh ledger, appends every delivered record and produces a snapshot. The snapshot is compared with the precomputed oracle result inside the timed loop so a wrong result fails the run.

The timed work includes dictionary construction, validation, duplicate and revision handling, grouping and final arithmetic. It excludes JSON parsing, file I/O, model calls, retrieval and any human acceptance work. It is therefore a ledger implementation measurement, not a measure of agent efficiency or end-to-end response time.

Three warm-up samples precede nine measured samples, each containing twenty complete replays. This is a small custom stopwatch harness rather than a statistically comprehensive performance suite. It provides enough evidence to inspect the implementation's cost at two declared input sizes without creating artificial large-scale load on the shared host.

Allocation uses `GC.GetAllocatedBytesForCurrentThread` around the synchronous loop. That measures managed allocation attributed to the current thread, not retained heap or native memory. The distinction matters because the ledger deliberately retains distinct revisions during a replay and releases the whole instance afterward. [Current-thread allocation counter](https://learn.microsoft.com/en-us/dotnet/api/system.gc.getallocatedbytesforcurrentthread?view=net-10.0&ref=devinside.cloud).

The records-per-second calculation counts delivered input records, including duplicates. It is not unique attempts per second, and it is certainly not accepted tasks per second from a live agent. Keeping that unit in the report prevents throughput from being inflated rhetorically by retry traffic.

The integrator ran the benchmark in the exclusive task-measurement lane on 12 November 2026 at 13:48 UTC. The process completed successfully on .NET 10.0.15, X64, Windows build 20348, with workstation GC. The shared host exposed 64 logical processors; that does not imply the single-threaded ledger used them all.

The table includes all four configurations and the full observed range of sample timings. Each value represents a complete fresh replay and snapshot, not one record. Allocation ranges are managed bytes per replay on the measured thread.

| Tasks | Delivered records | Arrival order | Median ms/replay | Observed ms range | Allocated bytes/replay range |
| ----- | ----------------- | ------------- | ---------------- | ----------------- | ---------------------------- |
| 100   | 500               | ordered       | 0.439            | 0.432–0.447       | 201,648–201,648              |
| 100   | 500               | shuffled      | 0.437            | 0.435–0.442       | 201,648–201,648              |
| 1,000 | 5,000             | ordered       | 3.482            | 1.777–5.282       | 1,988,264–1,992,264          |
| 1,000 | 5,000             | shuffled      | 2.005            | 1.981–2.024       | 1,992,264–1,992,264          |

The 100-task runs were close: both medians were about 0.44 milliseconds per replay. Their median delivered-record rates were approximately 1.14 million records per second. Those rates count the generated duplicate records and therefore cannot be interpreted as a million unique attempts or accepted tasks per second.

The 1,000-task ordered configuration was visibly unstable across these samples, spanning about 1.78 to 5.28 milliseconds. Its median was slower than the shuffled configuration, but this is not evidence that shuffling makes the ledger faster. The harness runs configurations in a fixed outer order within one process; tiered compilation, earlier execution and host activity are not independently controlled by this experiment. The result should be treated as a narrow observation with substantial variation, not a causal ranking of arrival orders.

Managed allocation was 201,648 bytes per 100-task replay. The 1,000-task ordered run recorded two allocation totals, 1,988,264 and 1,992,264 bytes, while the shuffled run recorded 1,992,264\. The experiment does not isolate the cause of that small allocation difference. Reporting the range is more honest than selecting the lower number as an intrinsic property of ordered input.

Every timed replay checked its snapshot against the oracle. The 100-task fixture produced 1,680 synthetic accounting units, 75 accepted tasks and a ratio of 22.4 units per accepted task. The 1,000-task fixture produced 16,986 units, 750 accepted tasks and a ratio of 22.648\. These are deterministic fixture arithmetic, not observed provider costs or measured model quality. Their small difference comes from the generated quantity pattern, not a discovery about scale economics.

The result demonstrates that the implementation can be measured while preserving the same ledger answer. It does not establish a production capacity limit, database write rate, streaming memory bound or performance improvement over another implementation. No alternative ledger was timed. If a future optimization is proposed, this correct implementation and its input manifests provide a baseline that the candidate must match.

## Decide what belongs outside this small ledger

The implementation intentionally does not claim zero allocation. Its dictionaries, retained revisions, grouping and manifest splitting trade memory for an inspectable model. Before optimizing those structures, decide which part of the workload matters: repeated batch rebuilds, incremental updates, snapshot frequency or long-lived retention.

A frequently refreshed dashboard might need cached aggregates and a different snapshot strategy. A durable ingestion service might need database uniqueness constraints and transactional conflict records. A high-volume stream may require partitioning by task identity, a retention policy and a sealed-workload manifest. Each change introduces correctness questions beyond choosing a faster collection.

For example, keeping only the highest revision can reduce memory but loses the ability to detect a conflicting older delivery. Removing old history is a policy decision about what the system promises to catch. It should not arrive disguised as a harmless allocation optimization.

Likewise, maintaining a running total requires reversing the contribution of an old revision before applying a correction. Overflow or failure midway through that update must not leave the aggregate inconsistent. The simpler snapshot calculation in this laboratory avoids that partially updated total by recomputing from current records. Its performance cost is visible, and a future optimization would have a precise invariant to preserve.

The acceptance decision belongs outside the cost calculator as well. A model judging its own answer is not automatically an independent quality gate. This ledger can preserve a supplied acceptance result and report its consequences, but the evidence supporting that result must come from the actual evaluation process. No live-model quality conclusion follows from a correct sum over synthetic labels.

The broader lesson is to preserve the type of every claim. An observed quantity is not an estimate. A known subtotal is not a complete total. A successful transport response is not an accepted task. A replay throughput measurement is not an agent benchmark. Once those distinctions survive the data model, the arithmetic becomes much harder to misuse.

## Reproduce the result and keep its scope attached

The project pins SDK 10.0.400 and runtime 10.0.15 locally, without changing global settings. It has no external service dependency or real pricing input. From the `lab` directory:

```powershell
dotnet run -c Release -- test
dotnet run -c Release --no-build -- example ../example
dotnet run -c Release --no-build -- bench ../benchmark-results.json

```

Run the benchmark in the designated exclusive measurement window. The first command validates the ledger contract; the second regenerates the concrete trace and CSV; the third measures the narrow synchronous replay mechanism. Their outputs have different meanings and should remain separate in the evidence pack.

The most valuable artifact is not a low synthetic unit cost. It is the ability to point from a reported number back to the tasks, attempt identities, current revisions and missing evidence that determined it. When the report cannot establish completeness, it says so without manufacturing a zero.

That is a useful foundation for comparing actual agent configurations later. Before bringing in a provider, a tariff or a quality evaluation, the application already has a tested way to preserve the relationship between work performed and outcomes accepted. Any later claim of lower cost will then have to survive an honest account of everything it took to finish the task.

## Source code and execution evidence

[Download the complete lab, source record and raw execution results](https://devinside.cloud/content/files/2026/11/AI01-lab.zip). This package supports the specific execution claims in this article. It is not a production certification.