You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maka.apache.org by li...@apache.org on 2026/10/08 23:42:31 UTC

(maka) branch main updated: fix(usage): record aborted auxiliary model calls as usage-unknown, not zero (#5890)

This is an automated email from the ASF dual-hosted git repository.

liugddx pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/maka.git


The following commit(s) were added to refs/heads/main by this push:
     new 3bd8bbe1e5 fix(usage): record aborted auxiliary model calls as usage-unknown, not zero (#5890)
3bd8bbe1e5 is described below

commit 3bd8bbe1e5a1ed12c6397345845fe9fe8ff68b0c
Author: 小七 <gg...@gmail.com>
AuthorDate: Fri Oct 9 07:42:25 2026 +0800

    fix(usage): record aborted auxiliary model calls as usage-unknown, not zero (#5890)
    
    A failed or aborted auxiliary model call recorded zero usage, so it read
    as free. Record it as usage-unknown (usage_basis = 'missing') with a
    no_run marker instead. Ledger-wide coverage keeps reporting these rows,
    while hosted-execution settlement checks the same window as its totals
    and excludes only the no_run sentinel rows, so delegated child Sessions
    still block settlement when their usage is missing. Bumps the usage
    schema to 10.
    
    Part of #5691.
    
    Generated-by: GLM-5.3-Flash (ZCode)
---
 .../__tests__/execution-model-composition.test.ts  | 220 ++++++++++++++++++++-
 .../src/__tests__/hosted-execution-runner.test.ts  |  58 +++++-
 .../src/server/execution-composition.ts            |   1 +
 .../src/server/execution-model-authority.ts        |  78 ++++++--
 .../src/server/hosted-execution-runner.ts          |  27 ++-
 .../src/server/usage-pricing-coordinator.ts        |  12 ++
 .../src/__tests__/model-call-usage-query.test.ts   | 216 ++++++++++++++++++++
 .../src/__tests__/public-entrypoints.test.ts       |  11 +-
 .../src/__tests__/sqlite-usage-schema.test.ts      |  44 +++++
 .../storage/src/__tests__/usage-stores.test.ts     | 109 ++++++++++
 packages/storage/src/model-call-ledger.ts          | 133 +++++++++++++
 packages/storage/src/model-call-usage-sql.ts       |  25 +++
 packages/storage/src/sqlite-usage-schema.ts        |  19 +-
 packages/storage/src/usage-stores.ts               |  22 +++
 14 files changed, 943 insertions(+), 32 deletions(-)

diff --git a/packages/runtime-host/src/__tests__/execution-model-composition.test.ts b/packages/runtime-host/src/__tests__/execution-model-composition.test.ts
index a38e4cee2a..89a7f06d47 100644
--- a/packages/runtime-host/src/__tests__/execution-model-composition.test.ts
+++ b/packages/runtime-host/src/__tests__/execution-model-composition.test.ts
@@ -4441,13 +4441,37 @@ test('Host auxiliary models meter provider usage and abort physical requests', {
       });
       await closing;
       assert.equal(transportCloses, 1);
-      const abortedLogs = await usage.telemetry.logs({ range: 'all' });
+      // An aborted auxiliary call knows no token counts: it records in the
+      // canonical ledger as a usage-unknown row (#5691), never as a zero-token
+      // legacy row that reads as a free call.
+      const abortedAttempts = await usage.modelCalls.modelCallLogs(
+        { range: 'all', sessionId: session.id },
+        Date.now(),
+        0,
+        10,
+      );
       assert.ok(
-        abortedLogs.rows.some(
+        abortedAttempts.projection.rows.some(
           (row) =>
             row.callId === `goal_evaluation_${session.id}_call-2` && row.status === 'aborted',
         ),
       );
+      const abortedSummary = await usage.modelCalls.modelCallSummary(
+        { range: 'all', sessionId: session.id },
+        Date.now(),
+      );
+      // Every failed auxiliary call above — the 401 recap, the timed-out
+      // recap, and the aborted goal evaluation — is recorded under the
+      // no-run sentinel turn, and the ledger-wide coverage still counts all
+      // three: real unknown-usage calls stay visible in the public
+      // provenance. Keeping a hosted run to its own rows is settlement's
+      // run-scoped check, not this field's job.
+      assert.equal(abortedSummary.projection.coverage.usageMissingAttempts, 3);
+      const abortedLegacyLogs = await usage.telemetry.logs({ range: 'all' });
+      assert.equal(
+        abortedLegacyLogs.rows.some((row) => row.callId === `goal_evaluation_${session.id}_call-2`),
+        false,
+      );
     } finally {
       abort.abort(new DOMException('Goal evaluator test cleanup', 'AbortError'));
       providerRelease.resolve();
@@ -4463,6 +4487,198 @@ test('Host auxiliary models meter provider usage and abort physical requests', {
   }
 });
 
+test('Host auxiliary aborts, errors and usage-unknown completions record canonical usage-unknown rows', {
+  timeout: 20_000,
+}, async () => {
+  const base = await mkdtemp(join(tmpdir(), 'maka-host-aux-usage-unknown-'));
+  const capability = await resolveStorageRoot({
+    path: join(base, 'interactive'),
+    kind: 'interactive',
+  });
+  const owner = await tryAcquireInteractiveRootOwner(capability);
+  assert.ok(owner);
+  if (!owner) return;
+
+  const policy = await openInteractiveRuntimePolicyStoresForWrite(owner.lease);
+  const usage = await openInteractiveUsageStoresForWrite(owner.lease);
+  const execution = await openInteractiveExecutionStoresForWrite(owner.lease);
+  try {
+    const created = await policy.connectionCatalog.create({
+      expectedCatalogRevision: 0,
+      connection: {
+        slug: 'usage-unknown-provider',
+        name: 'Usage unknown provider',
+        providerType: 'opencode-go',
+        baseUrl: 'http://usage-unknown.test/v1',
+        enabled: true,
+        enabledModelIds: [MODEL_ID],
+      },
+    });
+    assert.equal(created.kind, 'committed');
+    if (created.kind !== 'committed') return;
+    const connection = created.snapshot.connections[0];
+    assert.ok(connection);
+    if (!connection) return;
+    const credential = await policy.credentialVault.set({
+      locator: {
+        scope: 'connection',
+        connectionId: connection.connectionId,
+        kind: 'api_key',
+      },
+      expected: null,
+      secret: API_KEY,
+    });
+    assert.equal(credential.kind, 'committed');
+    await publishConnectionModel(policy, connection.connectionId, MODEL_ID);
+    const session = await execution.sessionStore.create({
+      cwd: capability.canonicalPath,
+      llmConnectionId: connection.connectionId,
+      llmConnectionSlug: 'usage-unknown-provider',
+      model: MODEL_ID,
+      permissionMode: 'ask',
+    });
+    let callCounter = 0;
+    const evaluator = (
+      fetchImpl: (request: unknown, init?: { signal?: AbortSignal }) => Promise<unknown>,
+    ) =>
+      createHostGoalEvaluator({
+        runtimePolicy: policy,
+        oauthCredentials: new HostOAuthExecutionAuthority(policy),
+        usage,
+        requestDrain: () => assert.fail('Auxiliary accounting must not drain the Host'),
+        readSessionHeader: (sessionId: string) =>
+          execution.sessionStore.readHeaderSnapshot(sessionId),
+        newId: () => `call-${++callCounter}`,
+        createFetchTransport: () => ({
+          fetch: fetchImpl as unknown as ProxiedFetchTransport['fetch'],
+          close: async () => undefined,
+        }),
+      });
+    const callId = (suffix: string) => `goal_evaluation_${session.id}_${suffix}`;
+    const canonicalRow = async (suffix: string) => {
+      const logs = await usage.modelCalls.modelCallLogs(
+        { range: 'all', sessionId: session.id },
+        Date.now(),
+        0,
+        10,
+      );
+      return logs.projection.rows.find((row) => row.callId === callId(suffix));
+    };
+    const legacyGoalRows = async () => {
+      const logs = await usage.telemetry.logs({ range: 'all' });
+      return logs.rows.filter((row) => row.callKind === 'goal_evaluation');
+    };
+    const assertSummary = async (expected: {
+      requests: number;
+      missing: number;
+      errors: number;
+    }) => {
+      const summary = await usage.modelCalls.modelCallSummary(
+        { range: 'all', sessionId: session.id },
+        Date.now(),
+      );
+      assert.equal(summary.projection.totalRequests, expected.requests);
+      // The ledger-wide coverage counts every usage-unknown row it holds —
+      // the auxiliary rows under test included, each recorded under the
+      // no-run sentinel turn. Hiding them here would make an incomplete
+      // total read as complete; settlement scopes itself to the run's own
+      // rows instead.
+      assert.equal(summary.projection.coverage.usageMissingAttempts, expected.missing);
+      assert.equal(summary.projection.coverage.usageReportedAttempts, 0);
+      assert.equal(summary.projection.errorRequests, expected.errors);
+      assert.equal(summary.projection.totalTokens.total, 0);
+      assert.equal(summary.projection.totalCostUsd, 0);
+    };
+
+    // Aborted mid-flight: usage can never be known, so the canonical row says
+    // so instead of posing as a free call in the legacy table.
+    let abortSignal: AbortSignal | undefined;
+    const abortDispatched = deferred<void>();
+    const abortReleased = deferred<void>();
+    const abortingEvaluator = evaluator(async (_request, init) => {
+      abortSignal = init?.signal ?? undefined;
+      abortDispatched.resolve();
+      await abortReleased.promise;
+      throw abortSignal?.reason ?? new DOMException('Aborted', 'AbortError');
+    });
+    const abort = new AbortController();
+    const abortedCall = abortingEvaluator.evaluate(
+      'Judge the completed Goal.',
+      session.id,
+      abort.signal,
+    );
+    await settleWithin(abortDispatched.promise);
+    abort.abort(new DOMException('Goal lane invalidated', 'AbortError'));
+    abortReleased.resolve();
+    await assert.rejects(settleWithin(abortedCall));
+    await assertSummary({ requests: 1, missing: 1, errors: 0 });
+    const abortedRow = await canonicalRow('call-1');
+    assert.ok(abortedRow);
+    assert.equal(abortedRow.status, 'aborted');
+    assert.equal(abortedRow.callKind, 'goal_evaluation');
+    assert.deepEqual(await legacyGoalRows(), []);
+
+    // A provider error without an abort is usage-unknown all the same.
+    const failingEvaluator = evaluator(async () => {
+      throw new Error('provider exploded');
+    });
+    await assert.rejects(
+      failingEvaluator.evaluate(
+        'Judge the completed Goal.',
+        session.id,
+        new AbortController().signal,
+      ),
+    );
+    await assertSummary({ requests: 2, missing: 2, errors: 1 });
+    const failedRow = await canonicalRow('call-2');
+    assert.ok(failedRow);
+    assert.equal(failedRow.status, 'error');
+    assert.equal(failedRow.errorClass, 'Error');
+    assert.deepEqual(await legacyGoalRows(), []);
+
+    // A completion the provider answered without usage stays on the legacy
+    // zero path for now: with settlement scoped to a run's own rows a
+    // canonical missing row here would no longer flip any hosted run
+    // indeterminate, so routing it to the canonical ledger is a free-standing
+    // recording question (#5691), not a settlement constraint. Aborted and
+    // failed calls above already keep their canonical usage-unknown rows.
+    const silentEvaluator = evaluator(async () =>
+      Response.json({
+        id: 'chatcmpl-usage-unknown',
+        object: 'chat.completion',
+        created: 1,
+        model: MODEL_ID,
+        choices: [
+          {
+            index: 0,
+            message: { role: 'assistant', content: RESPONSE_TEXT },
+            finish_reason: 'stop',
+          },
+        ],
+      }),
+    );
+    assert.equal(
+      await silentEvaluator.evaluate(
+        'Judge the completed Goal.',
+        session.id,
+        new AbortController().signal,
+      ),
+      RESPONSE_TEXT,
+    );
+    await assertSummary({ requests: 2, missing: 2, errors: 1 });
+    const silentLegacy = (await legacyGoalRows()).find((row) => row.callId === callId('call-3'));
+    assert.ok(silentLegacy);
+    assert.equal(silentLegacy.status, 'success');
+    assert.equal(silentLegacy.inputTokens, 0);
+    assert.equal(silentLegacy.outputTokens, 0);
+  } finally {
+    await usage.close();
+    await execution.sessionStore.close?.();
+    await owner.close();
+    await rm(base, { recursive: true, force: true });
+  }
+});
+
 test('one turn shares one canonical Skill inventory across prompt and lazy tools', async () => {
   const policy = {
     revision: 7,
diff --git a/packages/runtime-host/src/__tests__/hosted-execution-runner.test.ts b/packages/runtime-host/src/__tests__/hosted-execution-runner.test.ts
index 00608a64d2..40624dc78c 100644
--- a/packages/runtime-host/src/__tests__/hosted-execution-runner.test.ts
+++ b/packages/runtime-host/src/__tests__/hosted-execution-runner.test.ts
@@ -33,6 +33,7 @@ test('hosted execution reads usage only after execution residencies settle', asy
         return usageSummary();
       },
     }),
+    runSettlementCoverage: settlementCoverage(),
     context: context(),
     requestDrain: () => {},
     waitForExecutionResidencies: () => residency.promise,
@@ -62,11 +63,46 @@ test('hosted execution reads usage only after execution residencies settle', asy
   assert.equal(usageRead, true);
 });
 
-test('incomplete usage preserves its fixed safe cause', async () => {
+test('a run-owned unsettled attempt refuses settlement with its fixed safe cause', async () => {
+  const runner = new HostHostedExecutionRunner({
+    handlers: handlers({}),
+    runSettlementCoverage: settlementCoverage({ usageMissingAttempts: 1 }),
+    context: context(),
+    requestDrain: () => {},
+    waitForExecutionResidencies: async () => {},
+    waitForAllResidencies: async () => {},
+  });
+
+  const result = await runner.run(input(), new AbortController().signal);
+
+  assert.equal(result.failureReason, 'Runtime Host usage did not settle: missing_attempt_usage');
+});
+
+test('a run-owned partial attempt refuses settlement with its fixed safe cause', async () => {
+  const runner = new HostHostedExecutionRunner({
+    handlers: handlers({}),
+    runSettlementCoverage: settlementCoverage({ usagePartialAttempts: 1 }),
+    context: context(),
+    requestDrain: () => {},
+    waitForExecutionResidencies: async () => {},
+    waitForAllResidencies: async () => {},
+  });
+
+  const result = await runner.run(input(), new AbortController().signal);
+
+  assert.equal(result.failureReason, 'Runtime Host usage did not settle: partial_attempt_usage');
+});
+
+test('a usage-unknown row outside any run does not block settlement', async () => {
+  // The failed auxiliary call (#5691) is real accounting: the ledger-wide
+  // coverage — the public provenance every client reads — counts it as
+  // usage-missing. Settlement must not read that field: it holds the run to
+  // its own rows, and the run left none unsettled.
   const usage = usageSummary();
   usage.provenance.coverage.usageMissingAttempts = 1;
   const runner = new HostHostedExecutionRunner({
     handlers: handlers({ usage: () => usage }),
+    runSettlementCoverage: settlementCoverage(),
     context: context(),
     requestDrain: () => {},
     waitForExecutionResidencies: async () => {},
@@ -75,7 +111,7 @@ test('incomplete usage preserves its fixed safe cause', async () => {
 
   const result = await runner.run(input(), new AbortController().signal);
 
-  assert.equal(result.failureReason, 'Runtime Host usage did not settle: missing_attempt_usage');
+  assert.equal(result.kind, 'settled');
 });
 
 test('abort after terminal completion preserves the completed result', async () => {
@@ -98,6 +134,7 @@ async function runWithAbortAfterTerminal(query?: () => unknown) {
   const settling = deferred();
   const runner = new HostHostedExecutionRunner({
     handlers: handlers(query ? { query } : {}),
+    runSettlementCoverage: settlementCoverage(),
     context: context(),
     requestDrain: () => {},
     waitForExecutionResidencies: () => {
@@ -132,6 +169,7 @@ test('hosted execution cancellation drains the Host and waits for canonical stop
         return terminalTurn('cancelled');
       },
     }),
+    runSettlementCoverage: settlementCoverage(),
     context: context(),
     requestDrain: () => {
       drains += 1;
@@ -167,6 +205,7 @@ test('hosted execution cancellation before Turn admission starts no Turn', async
         turnStarts += 1;
       },
     }),
+    runSettlementCoverage: settlementCoverage(),
     context: context(),
     requestDrain: () => {},
     waitForExecutionResidencies: async () => {},
@@ -195,6 +234,7 @@ test('hosted execution cancellation remains active while Runtime continuations s
         return runningTurn();
       },
     }),
+    runSettlementCoverage: settlementCoverage(),
     context: context(),
     requestDrain: () => {
       drains += 1;
@@ -334,6 +374,20 @@ function usageSummary() {
   };
 }
 
+/**
+ * The run-scoped incompleteness check's stub: a hosted execution owns no
+ * usage-unknown rows unless the test says otherwise.
+ */
+function settlementCoverage(
+  overrides: { usageMissingAttempts?: number; usagePartialAttempts?: number } = {},
+) {
+  return async (_from: number, _to: number) => ({
+    usageMissingAttempts: 0,
+    usagePartialAttempts: 0,
+    ...overrides,
+  });
+}
+
 function emptySkillInvocation() {
   return { loaded: [], failed: [], receipts: [] };
 }
diff --git a/packages/runtime-host/src/server/execution-composition.ts b/packages/runtime-host/src/server/execution-composition.ts
index 907e088866..f9025cd333 100644
--- a/packages/runtime-host/src/server/execution-composition.ts
+++ b/packages/runtime-host/src/server/execution-composition.ts
@@ -2833,6 +2833,7 @@ export async function createExecutionRuntimeHostComposition(
         'turn.stop': turnControl.handlers['turn.stop'],
         'usage.query': usagePricing.handlers['usage.query'],
       },
+      runSettlementCoverage: (from, to) => usagePricing.runSettlementCoverage(from, to),
       context: {
         hostEpoch: context.hostEpoch,
         connectionId: 'hosted-execution',
diff --git a/packages/runtime-host/src/server/execution-model-authority.ts b/packages/runtime-host/src/server/execution-model-authority.ts
index 4f5fbb6d47..47fc6c2cb9 100644
--- a/packages/runtime-host/src/server/execution-model-authority.ts
+++ b/packages/runtime-host/src/server/execution-model-authority.ts
@@ -76,6 +76,8 @@ import { resolveModelRuntime } from '@maka/runtime/model-runtime';
 import { type BackendFactoryContext } from '@maka/runtime/session-manager';
 import { type GoalEvaluatorResource } from '@maka/runtime/goal-evaluator';
 import { type ModelMessage } from '@maka/runtime/model-protocol';
+import { type ModelCallAttemptStatus } from '@maka/core/model-call-attempt';
+import { NO_RUN_TURN_ID, type UsageUnknownModelCallRecord } from '@maka/storage/model-call-ledger';
 import {
   memoryExtractionMaxOutputTokens,
   type MemoryExtractionSourceSnapshot,
@@ -560,6 +562,9 @@ interface AuxiliaryModelCallAuthority {
       record: Parameters<InteractiveUsageStoresWriter['telemetry']['recordLlmCall']>[0],
     ): Promise<void>;
   };
+  readonly modelCalls: {
+    recordUsageUnknownAttempt(record: UsageUnknownModelCallRecord): Promise<void>;
+  };
   readonly requestDrain: () => void;
   readonly now: () => number;
   readonly newId: () => string;
@@ -605,6 +610,16 @@ interface HostAuxiliaryModelCallInput {
   ) => AuxiliaryModelRequest;
 }
 
+/**
+ * Turn placeholder for canonical rows of calls no run owns: auxiliary calls
+ * happen outside any turn, and the ledger's countable rows require the column.
+ * The storage side records the rows' no-run ownership from this seam, so a
+ * failed auxiliary call cannot flip a hosted run to indeterminate (#5691) —
+ * including a hosted execution legally named like this placeholder
+ * (#5890 review).
+ */
+const AUXILIARY_TURN_ID = NO_RUN_TURN_ID;
+
 function createAuxiliaryModelCallAuthority(
   input: AuxiliaryModelCallAuthorityInput,
 ): AuxiliaryModelCallAuthority {
@@ -629,6 +644,16 @@ function createAuxiliaryModelCallAuthority(
         }
       },
     },
+    modelCalls: {
+      recordUsageUnknownAttempt: async (record) => {
+        try {
+          await input.usage.modelCalls.recordUsageUnknownAttempt(record);
+        } catch (error) {
+          requestDrain();
+          throw error;
+        }
+      },
+    },
     requestDrain,
     now: input.now ?? Date.now,
     newId: input.newId ?? randomUUID,
@@ -703,6 +728,34 @@ async function runHostAuxiliaryModelCall(
       modelId: target.model,
       startedAt,
     };
+    // Abort and error paths know no token counts: their canonical row says
+    // usage-unknown (`usageBasis: 'missing'`, no tokens) instead of posing as a
+    // free call (#5691). Auxiliary calls run outside any AgentRun, so the
+    // canonical writer is this store seam, not the run's event stream.
+    const recordUsageUnknown = async (
+      status: ModelCallAttemptStatus,
+      errorClass?: string,
+    ): Promise<void> => {
+      const completedAt = authority.now();
+      try {
+        await authority.modelCalls.recordUsageUnknownAttempt({
+          attemptId: input.callId,
+          completedAt,
+          ...(input.telemetrySessionId ? { sessionId: input.telemetrySessionId } : {}),
+          logicalCallId: input.callId,
+          turnId: AUXILIARY_TURN_ID,
+          callKind: input.callKind,
+          connectionSlug: target.connection.slug,
+          providerId: target.connection.providerType,
+          modelId: target.model,
+          latencyMs: Math.max(0, completedAt - startedAt),
+          status,
+          ...(errorClass ? { errorClass } : {}),
+        });
+      } catch (accountingError) {
+        throw new AuxiliaryModelCallLocalError('accounting', accountingError);
+      }
+    };
     let result:
       | Awaited<ReturnType<typeof generateToolFreeModelCall>>
       | Awaited<ReturnType<typeof generateProviderPrefixModelCall>>;
@@ -743,21 +796,10 @@ async function runHostAuxiliaryModelCall(
       if (oauthFailure) throw oauthFailure;
     } catch (error) {
       const effectiveError = readDeferredOAuthFailure?.() ?? error;
-      try {
-        await recordLlmCallStrict(
-          { repo: authority.telemetry, lookupPricing: pricing },
-          {
-            ...baseRecord,
-            inputTokens: 0,
-            outputTokens: 0,
-            latencyMs: Math.max(0, authority.now() - startedAt),
-            status: input.abortSignal.aborted ? 'aborted' : 'error',
-            errorClass: evaluatorErrorClass(effectiveError),
-          },
-        );
-      } catch (accountingError) {
-        throw new AuxiliaryModelCallLocalError('accounting', accountingError);
-      }
+      await recordUsageUnknown(
+        input.abortSignal.aborted ? 'aborted' : 'failed',
+        evaluatorErrorClass(effectiveError),
+      );
       throw effectiveError;
     }
     try {
@@ -765,6 +807,12 @@ async function runHostAuxiliaryModelCall(
         { repo: authority.telemetry, lookupPricing: pricing },
         {
           ...baseRecord,
+          // A completion without reported usage stays on the legacy zero path:
+          // hosted execution settlement refuses any range containing
+          // usage-missing rows ('missing_attempt_usage'), so routing these
+          // rows to the canonical ledger marked every such hosted run
+          // indeterminate. The residual zero is known dishonesty, pending a
+          // ruling on that settlement coverage semantics (#5691).
           ...(result.usage
             ? llmCallUsageFields(result.usage)
             : { inputTokens: 0, outputTokens: 0 }),
diff --git a/packages/runtime-host/src/server/hosted-execution-runner.ts b/packages/runtime-host/src/server/hosted-execution-runner.ts
index ea38fdfa2b..243a700e4b 100644
--- a/packages/runtime-host/src/server/hosted-execution-runner.ts
+++ b/packages/runtime-host/src/server/hosted-execution-runner.ts
@@ -26,6 +26,7 @@ import type {
   TurnSnapshot,
   UsageQueryResult,
 } from '../protocol/index.js';
+import type { RunSettlementCoverage } from '@maka/storage/model-call-ledger';
 import type { ConnectionContext, OperationHandlerMap } from './operation-dispatcher.js';
 
 export interface HostHostedExecutionRunnerInput {
@@ -33,6 +34,14 @@ export interface HostHostedExecutionRunnerInput {
     OperationHandlerMap,
     'session.create' | 'turn.start' | 'turn.query' | 'turn.stop' | 'usage.query'
   >;
+  /**
+   * What the settlement window left unsettled (#5890). Settlement's
+   * incompleteness check reads this window-scoped answer instead of the
+   * `usage.query` coverage: that field is the ledger's public provenance and
+   * must keep counting usage-unknown rows no run owns — a failed auxiliary
+   * Host call is real accounting, not this run's unsettled obligation.
+   */
+  readonly runSettlementCoverage: (from: number, to: number) => Promise<RunSettlementCoverage>;
   readonly context: ConnectionContext;
   readonly requestDrain: () => void;
   readonly waitForExecutionResidencies: () => Promise<void>;
@@ -82,8 +91,10 @@ export class HostHostedExecutionRunner {
       await (signal.aborted
         ? this.input.waitForAllResidencies()
         : this.input.waitForExecutionResidencies());
-      const usage = await this.#readUsage(startedAt, (this.input.now ?? Date.now)());
-      const incompleteUsage = incompleteUsageReason(usage);
+      const settledAt = (this.input.now ?? Date.now)();
+      const usage = await this.#readUsage(startedAt, settledAt);
+      const runCoverage = await this.input.runSettlementCoverage(startedAt, settledAt);
+      const incompleteUsage = incompleteUsageReason(usage, runCoverage);
       if (incompleteUsage) {
         return indeterminate(
           input.executionId,
@@ -160,12 +171,18 @@ export class HostHostedExecutionRunner {
 
 function incompleteUsageReason(
   result: Extract<UsageQueryResult, { kind: 'summary' }>,
+  runCoverage: RunSettlementCoverage,
 ): string | undefined {
-  const { coverage, unreadableRecords, pendingRepairs } = result.provenance;
+  // Unreadable and pending-repair rows stay ledger-wide: damage in the window
+  // is nobody's settled fact. Partial and missing usage are judged against the
+  // same window as the totals this check guards (#5890), so a delegated child
+  // Session cannot settle underneath them — the `no_run` sentinel rows stay
+  // excluded, and the shared coverage field still reports everything.
+  const { unreadableRecords, pendingRepairs } = result.provenance;
   if (unreadableRecords > 0) return 'unreadable_usage_record';
   if (pendingRepairs > 0) return 'pending_usage_repair';
-  if (coverage.usagePartialAttempts > 0) return 'partial_attempt_usage';
-  if (coverage.usageMissingAttempts > 0) return 'missing_attempt_usage';
+  if (runCoverage.usagePartialAttempts > 0) return 'partial_attempt_usage';
+  if (runCoverage.usageMissingAttempts > 0) return 'missing_attempt_usage';
   return undefined;
 }
 
diff --git a/packages/runtime-host/src/server/usage-pricing-coordinator.ts b/packages/runtime-host/src/server/usage-pricing-coordinator.ts
index 4b97e790d2..b5dcebcafe 100644
--- a/packages/runtime-host/src/server/usage-pricing-coordinator.ts
+++ b/packages/runtime-host/src/server/usage-pricing-coordinator.ts
@@ -42,6 +42,7 @@ import {
   type InteractiveUsageStoresFailureClassification,
   type InteractiveUsageStoresWriter,
 } from '@maka/storage/usage-stores';
+import type { RunSettlementCoverage } from '@maka/storage/model-call-ledger';
 import { isSessionNotFoundError } from '@maka/storage/execution-stores';
 import {
   encodePricingQueryResult,
@@ -80,6 +81,17 @@ export class HostUsagePricingCoordinator {
     'pricing.mutate': (input) => this.#mutatePricing(input),
   };
 
+  /**
+   * What the settlement window itself left unsettled (#5890) — hosted
+   * execution settlement's incompleteness check reads the same window as the
+   * totals it guards, minus the `no_run` sentinel rows. Deliberately off the
+   * operation handler map: the ledger-wide `usage.query` coverage keeps a
+   * different shape, so settlement scopes itself through this in-process seam.
+   */
+  async runSettlementCoverage(from: number, to: number): Promise<RunSettlementCoverage> {
+    return this.#stores.modelCalls.modelCallRunSettlementCoverage(from, to);
+  }
+
   readonly #stores: InteractiveUsageStoresWriter;
   readonly #requestDrain: () => void;
   readonly #activation: RuntimePolicyActivationGate;
diff --git a/packages/storage/src/__tests__/model-call-usage-query.test.ts b/packages/storage/src/__tests__/model-call-usage-query.test.ts
index 195f41576c..fca884393c 100644
--- a/packages/storage/src/__tests__/model-call-usage-query.test.ts
+++ b/packages/storage/src/__tests__/model-call-usage-query.test.ts
@@ -19,14 +19,62 @@
 
 import assert from 'node:assert/strict';
 import { describe, test } from 'node:test';
+import type { ModelCallAttempt } from '@maka/core/model-call-attempt';
 import {
+  type ModelCallLedger,
+  NO_RUN_TURN_ID,
+  type UsageUnknownModelCallRecord,
+} from '../model-call-ledger.js';
+import {
+  appendAuthorityEvent,
   modelCallAttempt as attempt,
   MODEL_CALL_NOW as NOW,
+  withLedger,
   withProjectedAttempts,
 } from './fixtures/model-call-attempt.js';
 
 const ALL = { range: 'all' } as const;
 
+/**
+ * Seeds rows the way production writes them: run-owned attempts through the
+ * AgentRun authority's projection, calls no run owns through the usage-unknown
+ * seam. Ownership follows the writer, so a test cannot fake a no-run row by
+ * projecting a sentinel turn value.
+ */
+async function withRecordedAttempts(
+  projected: readonly ModelCallAttempt[],
+  noRun: readonly UsageUnknownModelCallRecord[],
+  run: (ledger: ModelCallLedger) => Promise<void>,
+): Promise<void> {
+  await withLedger(async (ledger, root) => {
+    projected.forEach((value, index) => {
+      appendAuthorityEvent(root, index, value, value.sessionId, value.runId);
+    });
+    await ledger.catchUpProjection();
+    for (const record of noRun) await ledger.recordUsageUnknownAttempt(record);
+    await run(ledger);
+  });
+}
+
+/** A failed auxiliary Host call, as the usage-unknown seam records it. */
+function usageUnknownAttempt(
+  overrides: Partial<UsageUnknownModelCallRecord> = {},
+): UsageUnknownModelCallRecord {
+  return {
+    attemptId: 'auxiliary-failure',
+    completedAt: NOW - 100,
+    sessionId: 'session-1',
+    logicalCallId: 'auxiliary-failure',
+    turnId: NO_RUN_TURN_ID,
+    callKind: 'goal_evaluation',
+    providerId: 'openai',
+    modelId: 'gpt-5',
+    latencyMs: 5,
+    status: 'failed',
+    ...overrides,
+  };
+}
+
 describe('Usage answers over the canonical ledger', () => {
   test('a total never counts unpriced spend as zero, and says so in coverage', async () => {
     // The frozen pre-cutover table had nowhere to record "we could not price
@@ -99,6 +147,174 @@ describe('Usage answers over the canonical ledger', () => {
     );
   });
 
+  test('ledger coverage counts usage-unknown rows recorded outside any run', async () => {
+    // A failed auxiliary call (#5691) is accounted the same honest way as a
+    // run's own unsettled dispatch, and the ledger-wide coverage — what
+    // `summary()`/`logs()` report to every client — must see both. Excluding
+    // the no-run rows here would hide a real unknown-usage call from the
+    // public provenance and let an incomplete total read as complete; keeping
+    // a hosted run to its own rows is settlement's separate job.
+    await withRecordedAttempts(
+      [
+        attempt({
+          attemptId: 'run-dispatch',
+          status: 'failed',
+          usageBasis: 'missing',
+          inputTokens: undefined,
+          outputTokens: undefined,
+          costBasis: 'unpriced',
+          costUsd: undefined,
+        }),
+      ],
+      [usageUnknownAttempt()],
+      async (ledger) => {
+        const { projection } = ledger.summary(ALL, NOW);
+        assert.equal(projection.coverage.usageMissingAttempts, 2);
+        assert.equal(projection.coverage.usageReportedAttempts, 0);
+        assert.equal(projection.totalRequests, 2);
+      },
+    );
+  });
+
+  test('run settlement coverage guards every session in the window, not the auxiliary sentinel', async () => {
+    // Settlement guards the window-wide totals, so it must count every
+    // Session's unsettled dispatch in that window (#5890): the pre-window
+    // session filter here would have let a delegated child's missing usage
+    // settle as complete. The `no_run` sentinel — the failed auxiliary call
+    // the usage-unknown seam recorded — belongs to no run and stays out.
+    await withRecordedAttempts(
+      [
+        attempt({
+          attemptId: 'other-session-dispatch',
+          sessionId: 'session-2',
+          status: 'failed',
+          usageBasis: 'missing',
+          inputTokens: undefined,
+          outputTokens: undefined,
+          costBasis: 'unpriced',
+          costUsd: undefined,
+        }),
+        attempt({
+          attemptId: 'run-reported',
+          logicalCallId: 'call-2',
+        }),
+        attempt({
+          attemptId: 'run-partial',
+          logicalCallId: 'call-3',
+          usageBasis: 'partial',
+          outputTokens: undefined,
+        }),
+        attempt({
+          attemptId: 'run-missing-dispatch',
+          logicalCallId: 'call-4',
+          status: 'failed',
+          usageBasis: 'missing',
+          inputTokens: undefined,
+          outputTokens: undefined,
+          costBasis: 'unpriced',
+          costUsd: undefined,
+        }),
+      ],
+      [usageUnknownAttempt()],
+      async (ledger) => {
+        // The run's own missing dispatch and the other session's (a delegated
+        // child's) both count; the `no_run` sentinel does not.
+        assert.deepEqual(ledger.runSettlementCoverage(NOW - 1_000, NOW), {
+          usageMissingAttempts: 2,
+          usagePartialAttempts: 1,
+        });
+      },
+    );
+  });
+
+  test('run settlement coverage excludes the no-run sentinel, not an execution named like it', async () => {
+    // The exclusion must key on how a row was recorded (`no_run`), never on
+    // the turn value: a hosted execution whose id is the client-chosen
+    // `auxiliary` owns rows under `turn_id = 'auxiliary'`, and with window
+    // scoping (#5890) those must keep counting while the genuine sentinel row
+    // next to them stays out — or this execution's missing-usage dispatch
+    // disappears and `incompleteUsageReason` releases the environment with
+    // unknown usage.
+    await withRecordedAttempts(
+      [
+        attempt({
+          attemptId: 'run-reported',
+          sessionId: 'auxiliary',
+          runId: 'run-auxiliary',
+          turnId: 'auxiliary',
+          logicalCallId: 'call-reported',
+        }),
+        attempt({
+          attemptId: 'run-missing-dispatch',
+          sessionId: 'auxiliary',
+          runId: 'run-auxiliary',
+          turnId: 'auxiliary',
+          logicalCallId: 'call-missing',
+          status: 'failed',
+          usageBasis: 'missing',
+          inputTokens: undefined,
+          outputTokens: undefined,
+          costBasis: 'unpriced',
+          costUsd: undefined,
+        }),
+      ],
+      [usageUnknownAttempt({ sessionId: 'auxiliary' })],
+      async (ledger) => {
+        // The run-owned missing dispatch is this execution's unsettled
+        // obligation and counts inside the window; the failed auxiliary call
+        // is nobody's (`no_run`) and stays excluded. Public coverage keeps
+        // counting both.
+        assert.deepEqual(ledger.runSettlementCoverage(NOW - 1_000, NOW), {
+          usageMissingAttempts: 1,
+          usagePartialAttempts: 0,
+        });
+        assert.equal(
+          ledger.summary({ range: 'all' }, NOW).projection.coverage.usageMissingAttempts,
+          2,
+        );
+      },
+    );
+  });
+
+  test('run settlement coverage reads the window, not one session (#5890 review)', async () => {
+    // Settlement guards the window-wide totals that #readUsage reads, so its
+    // coverage must read the same window: a child Session's missing dispatch
+    // inside the window is exactly the undercount that would otherwise settle
+    // as complete, and a window-external row is nobody's obligation here.
+    await withRecordedAttempts(
+      [
+        attempt({
+          attemptId: 'outside-window-missing',
+          completedAt: NOW - 5_000,
+          status: 'failed',
+          usageBasis: 'missing',
+          inputTokens: undefined,
+          outputTokens: undefined,
+          costBasis: 'unpriced',
+          costUsd: undefined,
+        }),
+        attempt({ attemptId: 'root-ok' }),
+        attempt({
+          attemptId: 'child-missing',
+          sessionId: 'session-1-child',
+          status: 'failed',
+          usageBasis: 'missing',
+          inputTokens: undefined,
+          outputTokens: undefined,
+          costBasis: 'unpriced',
+          costUsd: undefined,
+        }),
+      ],
+      [],
+      async (ledger) => {
+        assert.deepEqual(ledger.runSettlementCoverage(NOW - 1_000, NOW), {
+          usageMissingAttempts: 1,
+          usagePartialAttempts: 0,
+        });
+      },
+    );
+  });
+
   test('one malformed cache reading cannot inflate the cache total', async () => {
     await withProjectedAttempts(
       [
diff --git a/packages/storage/src/__tests__/public-entrypoints.test.ts b/packages/storage/src/__tests__/public-entrypoints.test.ts
index a82c61b94d..f17906149c 100644
--- a/packages/storage/src/__tests__/public-entrypoints.test.ts
+++ b/packages/storage/src/__tests__/public-entrypoints.test.ts
@@ -140,17 +140,16 @@ test('every published entrypoint target is emitted by the build', async () => {
  * means removing the entry, and publishing a *new* consumer-less entrypoint
  * fails outright, which is the direction this guard exists to hold.
  *
- * `./model-call-ledger` is on the list without this change touching it: it was
- * already published, and `repairPendingModelCallProjections` lost its last
- * caller when `canonical-usage-reader` was rewritten on `main`. It is listed
- * here rather than unpublished for the same reason as the rest — retiring a
- * subpath that already shipped is a compatibility call of its own.
+ * `./model-call-ledger` was on this list until the usage-unknown seam
+ * (`fix(usage)`): it had been published without consumers since
+ * `repairPendingModelCallProjections` lost its last caller when
+ * `canonical-usage-reader` was rewritten on `main`; the auxiliary-call
+ * recorder in runtime-host is its first external consumer again.
  */
 const PREEXISTING_UNCONSUMED_ENTRYPOINTS = [
   './activation-secret-injector',
   './encrypted-file-managed-secret-store',
   './managed-secret-store',
-  './model-call-ledger',
   './write-queue',
 ];
 
diff --git a/packages/storage/src/__tests__/sqlite-usage-schema.test.ts b/packages/storage/src/__tests__/sqlite-usage-schema.test.ts
index f84590b3b5..2ac5213bbe 100644
--- a/packages/storage/src/__tests__/sqlite-usage-schema.test.ts
+++ b/packages/storage/src/__tests__/sqlite-usage-schema.test.ts
@@ -21,6 +21,15 @@ import assert from 'node:assert/strict';
 import { DatabaseSync } from 'node:sqlite';
 import { test } from 'node:test';
 import { migrateSqliteUsageDatabase } from '../sqlite-usage-schema.js';
+import {
+  assertCurrentOperationalTargetSchema,
+  ensureOperationalSchemaRegistry,
+} from '../operational-target-schema.js';
+import { migrateSqliteArtifactDatabase } from '../sqlite-artifact-schema.js';
+import { migrateSqliteCoreExecutionDatabase } from '../sqlite-core-execution-schema.js';
+import { migrateSqliteRuntimeDatabase } from '../sqlite-runtime-schema.js';
+import { migrateSqliteSessionMetadataDatabase } from '../sqlite-session-metadata-schema.js';
+import { migrateSqliteWorkflowDatabase } from '../sqlite-workflow-schema.js';
 import {
   MODEL_CALL_NOW as NOW,
   modelCallAttempt as attempt,
@@ -331,3 +340,38 @@ test('Usage title revision ignores unrelated metadata and covers every activity
     database.close();
   }
 });
+
+test('a schema-9 usage database upgrades to the target shape and stays idempotent', () => {
+  const database = new DatabaseSync(':memory:');
+  try {
+    // Build the full operational target, then regress usage to its schema-9
+    // shape. The #5890 target adds `no_run` as the usage delta, so a real
+    // schema-9 database is exactly this table minus that column.
+    migrateSqliteRuntimeDatabase(database);
+    migrateSqliteSessionMetadataDatabase(database);
+    migrateSqliteCoreExecutionDatabase(database);
+    migrateSqliteWorkflowDatabase(database);
+    migrateSqliteUsageDatabase(database);
+    migrateSqliteArtifactDatabase(database);
+    ensureOperationalSchemaRegistry(database);
+    database.exec('ALTER TABLE usage_model_call_attempts DROP COLUMN no_run');
+
+    migrateSqliteUsageDatabase(database);
+
+    // The upgrade restores the recorder-owned default in place — the DDL
+    // signature matches a fresh create only because ADD COLUMN appends the
+    // column the same way — and a rerun changes nothing.
+    assertCurrentOperationalTargetSchema(database);
+    const restored = database
+      .prepare(
+        "SELECT \"notnull\" AS not_null, dflt_value FROM pragma_table_info('usage_model_call_attempts') WHERE name = 'no_run'",
+      )
+      .get() as { not_null: number; dflt_value: string };
+    assert.equal(restored.not_null, 1);
+    assert.equal(restored.dflt_value, '0');
+    migrateSqliteUsageDatabase(database);
+    assertCurrentOperationalTargetSchema(database);
+  } finally {
+    database.close();
+  }
+});
diff --git a/packages/storage/src/__tests__/usage-stores.test.ts b/packages/storage/src/__tests__/usage-stores.test.ts
index 023f5f4cd0..3de89e5cf0 100644
--- a/packages/storage/src/__tests__/usage-stores.test.ts
+++ b/packages/storage/src/__tests__/usage-stores.test.ts
@@ -185,6 +185,115 @@ describe('InteractiveUsageStores', () => {
     });
   });
 
+  test('records a usage-unknown auxiliary call as a canonical row without token counts', async () => {
+    await withInteractiveRoot(async ({ root, capability }) => {
+      const owner = await tryAcquireInteractiveRootOwner(capability);
+      assert(owner);
+      const stores = await openInteractiveUsageStoresForWrite(owner.lease);
+      const changed: string[] = [];
+      const unsubscribe = stores.subscribeSessionUsageChanges((sessionId) =>
+        changed.push(sessionId),
+      );
+      try {
+        // An auxiliary call aborted mid-flight knows no token counts. Its row
+        // must say so (usage_basis 'missing', no tokens) instead of posing as a
+        // free call — the same facts the run-path projection records.
+        const record = {
+          attemptId: 'goal_evaluation_session-aux_call-1',
+          completedAt: Date.UTC(2026, 0, 1),
+          sessionId: 'session-aux',
+          logicalCallId: 'goal_evaluation_session-aux_call-1',
+          turnId: 'auxiliary',
+          callKind: 'goal_evaluation' as const,
+          connectionSlug: 'conn-aux',
+          providerId: 'openai',
+          modelId: 'gpt-5',
+          latencyMs: 120,
+          status: 'aborted' as const,
+          errorClass: 'AbortError',
+        };
+        await stores.modelCalls.recordUsageUnknownAttempt(record);
+        assert.deepEqual(changed, ['session-aux']);
+
+        const summary = await stores.modelCalls.modelCallSummary({ range: 'all' }, Date.now());
+        assert.equal(summary.projection.totalRequests, 1);
+        assert.equal(summary.projection.totalCostUsd, 0);
+        assert.equal(summary.projection.totalTokens.total, 0);
+        // The ledger-wide coverage counts the row: a real unknown-usage call
+        // must stay visible in the public provenance even though it belongs to
+        // no run. Keeping a hosted run to its own rows is the run-scoped
+        // settlement coverage's job, asserted against the same stores below.
+        assert.equal(summary.projection.coverage.usageMissingAttempts, 1);
+        assert.equal(summary.projection.coverage.usageReportedAttempts, 0);
+        assert.equal(summary.unreadableRecords, 0);
+        // The settlement coverage excludes the no-run sentinel row — its
+        // usage_basis never enters any run's window scope — so an auxiliary
+        // failure cannot flip a hosted run to indeterminate.
+        assert.deepEqual(await stores.modelCalls.modelCallRunSettlementCoverage(0, Date.now()), {
+          usageMissingAttempts: 0,
+          usagePartialAttempts: 0,
+        });
+
+        const logs = await stores.modelCalls.modelCallLogs({ range: 'all' }, Date.now(), 0, 10);
+        assert.equal(logs.projection.total, 1);
+        const row = logs.projection.rows[0];
+        assert.ok(row);
+        assert.equal(row.callId, 'goal_evaluation_session-aux_call-1');
+        assert.equal(row.callKind, 'goal_evaluation');
+        assert.equal(row.status, 'aborted');
+        assert.equal(row.errorClass, 'AbortError');
+
+        // The schema CHECK is the hard edge: a missing-usage row carries no
+        // token counts at all, so no total can mistake it for a free call.
+        const db = acquireOperationalStateDatabase(root);
+        try {
+          const stored = db.database
+            .prepare(
+              `SELECT usage_basis, cost_basis, cost_usd, input_tokens, output_tokens,
+                      cache_read_input_tokens, cache_miss_input_tokens,
+                      cache_write_input_tokens, reasoning_tokens,
+                      status, session_id, turn_id
+               FROM usage_model_call_attempts WHERE attempt_id = ?`,
+            )
+            .get('goal_evaluation_session-aux_call-1');
+          assert.deepEqual(
+            { ...stored },
+            {
+              usage_basis: 'missing',
+              cost_basis: 'unpriced',
+              cost_usd: null,
+              input_tokens: null,
+              output_tokens: null,
+              cache_read_input_tokens: null,
+              cache_miss_input_tokens: null,
+              cache_write_input_tokens: null,
+              reasoning_tokens: null,
+              status: 'aborted',
+              session_id: 'session-aux',
+              turn_id: 'auxiliary',
+            },
+          );
+        } finally {
+          db.close();
+        }
+
+        // Re-recording the same attempt upserts in place instead of double
+        // counting the call.
+        await stores.modelCalls.recordUsageUnknownAttempt({
+          ...record,
+          latencyMs: 130,
+        });
+        const resummarized = await stores.modelCalls.modelCallSummary({ range: 'all' }, Date.now());
+        assert.equal(resummarized.projection.totalRequests, 1);
+        assert.deepEqual(changed, ['session-aux', 'session-aux']);
+      } finally {
+        unsubscribe();
+        await stores.close();
+        await owner.close();
+      }
+    });
+  });
+
   test('publishes the owning Session after a durable tool-usage write', async () => {
     await withInteractiveRoot(async ({ capability }) => {
       const owner = await tryAcquireInteractiveRootOwner(capability);
diff --git a/packages/storage/src/model-call-ledger.ts b/packages/storage/src/model-call-ledger.ts
index eee51d310e..69ee75d124 100644
--- a/packages/storage/src/model-call-ledger.ts
+++ b/packages/storage/src/model-call-ledger.ts
@@ -21,6 +21,7 @@ import {
   decodeModelCallAttempt,
   MODEL_CALL_ATTEMPT_EVENT_TYPE,
   type ModelCallAttempt,
+  type ModelCallAttemptStatus,
   type ModelCallCoverage,
 } from '@maka/core/model-call-attempt';
 import {
@@ -31,6 +32,7 @@ import {
 } from '@maka/core/model-call-usage-projection';
 import { usageBucketKey } from '@maka/core/usage-stats/bucket-key';
 import type {
+  ModelCallKind,
   UsageBucket,
   UsageGroupBy,
   UsageLogRow,
@@ -43,8 +45,10 @@ import {
   count,
   countableFilter,
   COVERAGE_SUMS,
+  NO_RUN_TURN_ID,
   PRICED_COST,
   REQUEST_SUMS,
+  RUN_SETTLEMENT_COVERAGE_SUMS,
   TOKEN_SUMS,
   unreadableFilter,
   type SqlFilter,
@@ -56,6 +60,8 @@ import {
 import { MODEL_CALL_COLUMNS } from './sqlite-usage-schema.js';
 import type { ModelCallLedgerResult } from './usage-stores.js';
 
+export { NO_RUN_TURN_ID };
+
 /**
  * Materialization of the canonical model-call accounting ledger (#1679).
  *
@@ -116,6 +122,26 @@ export interface ModelCallLedgerReader {
     offset: number,
     limit: number,
   ): ModelCallLedgerResult<ModelCallUsageLogs>;
+  /**
+   * What the settlement window itself left unsettled (#5890): the attempts
+   * between `from` and `to` inclusive whose usage the provider never reported
+   * or only partly reported, across every Session — the same scope as the
+   * window-wide totals this check guards. Rows recorded outside any run — by
+   * the usage-unknown seam, which the ledger marks `no_run` — belong to no
+   * run's settlement and are excluded, the reverse of the ledger-wide
+   * coverage above, which must see them.
+   */
+  runSettlementCoverage(from: number, to: number): RunSettlementCoverage;
+}
+
+/**
+ * What a hosted execution's settlement checks instead of the ledger-wide
+ * coverage: whether everything in the window settled (#5890, widening #5691's
+ * run-owned scope so delegated Sessions cannot settle underneath it).
+ */
+export interface RunSettlementCoverage {
+  readonly usageMissingAttempts: number;
+  readonly usagePartialAttempts: number;
 }
 
 export interface CatchUpModelCallProjectionInput {
@@ -133,11 +159,51 @@ export interface CatchUpModelCallProjectionResult {
   readonly unreadableEvents: number;
 }
 
+/**
+ * One canonical row for a call no AgentRun owns (#5691).
+ *
+ * Auxiliary Host model calls run outside any run, so nothing projects them
+ * from an event stream — the caller carries the row's identity itself. Usage
+ * cannot be known for these calls (the provider never reported it), so the
+ * record cannot express token counts or a cost: it lands as
+ * `usageBasis: 'missing'` / `costBasis: 'unpriced'`, the same facts the
+ * run-path projection records and the same rule the table's CHECK enforces on
+ * every other writer.
+ */
+export interface UsageUnknownModelCallRecord {
+  /** Idempotency key: recording the same attempt twice stores one row. */
+  readonly attemptId: string;
+  readonly completedAt: number;
+  readonly sessionId?: string;
+  readonly logicalCallId: string;
+  /**
+   * Calls outside any run's turn carry the shared no-run sentinel
+   * (`NO_RUN_TURN_ID`) — the table requires the column for every countable
+   * row. The value is a placeholder, not the discriminator: the ledger
+   * records the row's no-run ownership from this seam itself, so an
+   * execution legally named like the sentinel keeps its own rows.
+   */
+  readonly turnId: string;
+  readonly callKind: ModelCallKind;
+  readonly connectionSlug?: string;
+  readonly providerId: string;
+  readonly modelId: string;
+  readonly latencyMs: number;
+  readonly status: ModelCallAttemptStatus;
+  readonly errorClass?: string;
+}
+
 export interface ModelCallLedgerWriter extends ModelCallLedgerReader {
   /** Advances the read model from the AgentRun authority's durable sequence. */
   catchUpProjection(
     input?: CatchUpModelCallProjectionInput,
   ): Promise<CatchUpModelCallProjectionResult>;
+  /**
+   * Records one usage-unknown row for a call outside any AgentRun. The single
+   * write that does not come from the event stream: the caller owns the
+   * attempt's identity, and re-recording an `attemptId` upserts in place.
+   */
+  recordUsageUnknownAttempt(record: UsageUnknownModelCallRecord): Promise<void>;
 }
 
 export interface ModelCallLedger extends ModelCallLedgerWriter {
@@ -209,6 +275,11 @@ class SqliteModelCallLedger implements ModelCallLedger {
     );
   }
 
+  recordUsageUnknownAttempt(record: UsageUnknownModelCallRecord): Promise<void> {
+    if (this.#state !== 'open') return Promise.reject(new ModelCallLedgerClosedError());
+    return this.write(() => writeUsageUnknownModelCallAttempt(this.#lease.database, record));
+  }
+
   summary(query: UsageQuery, now: number): ModelCallLedgerResult<ModelCallUsageSummary> {
     const db = this.#open();
     const range = resolveUsageRange(query.range, now);
@@ -320,6 +391,22 @@ class SqliteModelCallLedger implements ModelCallLedger {
     };
   }
 
+  runSettlementCoverage(from: number, to: number): RunSettlementCoverage {
+    const db = this.#open();
+    const row = db
+      .prepare(
+        `SELECT ${RUN_SETTLEMENT_COVERAGE_SUMS}
+         FROM usage_model_call_attempts
+         WHERE cost_basis IS NOT NULL AND no_run = 0
+           AND completed_at >= ? AND completed_at <= ?`,
+      )
+      .get(from, to) as Record<string, unknown> | undefined;
+    return {
+      usageMissingAttempts: count(row?.usageMissingAttempts),
+      usagePartialAttempts: count(row?.usagePartialAttempts),
+    };
+  }
+
   #open(): DatabaseSync {
     if (this.#state !== 'open') throw new ModelCallLedgerClosedError();
     return this.#lease.database;
@@ -463,6 +550,9 @@ function bindModelCallAttempt(attempt: ModelCallAttempt): (string | number | nul
     reasoning_tokens: attempt.reasoningTokens ?? null,
     cost_basis: attempt.costBasis,
     cost_usd: attempt.costUsd ?? null,
+    // The projection's only source is the AgentRun authority: every row it
+    // writes is run-owned, whatever turn the run ran under.
+    no_run: 0,
   };
   return MODEL_CALL_COLUMNS.map((column) => values[column]);
 }
@@ -471,6 +561,49 @@ function writeModelCallAttempt(db: DatabaseSync, attempt: ModelCallAttempt): voi
   db.prepare(MODEL_CALL_UPSERT).run(...bindModelCallAttempt(attempt));
 }
 
+/**
+ * The usage-unknown binding: no token counts and no cost exist to record, and
+ * the table's CHECKs refuse any row that claimed otherwise.
+ */
+function bindUsageUnknownModelCallAttempt(
+  record: UsageUnknownModelCallRecord,
+): (string | number | null)[] {
+  const values: Record<(typeof MODEL_CALL_COLUMNS)[number], string | number | null> = {
+    attempt_id: record.attemptId,
+    completed_at: record.completedAt,
+    session_id: record.sessionId ?? null,
+    logical_call_id: record.logicalCallId,
+    turn_id: record.turnId,
+    call_kind: record.callKind,
+    connection_slug: record.connectionSlug ?? null,
+    provider_id: record.providerId,
+    model_id: record.modelId,
+    latency_ms: record.latencyMs,
+    status: record.status,
+    error_class: record.errorClass ?? null,
+    usage_basis: 'missing',
+    input_tokens: null,
+    output_tokens: null,
+    cache_read_input_tokens: null,
+    cache_miss_input_tokens: null,
+    cache_write_input_tokens: null,
+    reasoning_tokens: null,
+    cost_basis: 'unpriced',
+    cost_usd: null,
+    // The one write outside any run's event stream: the ledger marks the row
+    // no-run here rather than inferring ownership from the turn value.
+    no_run: 1,
+  };
+  return MODEL_CALL_COLUMNS.map((column) => values[column]);
+}
+
+function writeUsageUnknownModelCallAttempt(
+  db: DatabaseSync,
+  record: UsageUnknownModelCallRecord,
+): void {
+  db.prepare(MODEL_CALL_UPSERT).run(...bindUsageUnknownModelCallAttempt(record));
+}
+
 interface LaggingRunRow {
   readonly session_id: string;
   readonly run_id: string;
diff --git a/packages/storage/src/model-call-usage-sql.ts b/packages/storage/src/model-call-usage-sql.ts
index e44ab50d69..fb7e890841 100644
--- a/packages/storage/src/model-call-usage-sql.ts
+++ b/packages/storage/src/model-call-usage-sql.ts
@@ -43,6 +43,18 @@ export const PRICED_COST = `CASE WHEN cost_basis = 'priced' THEN COALESCE(cost_u
 /** Only a provider failure is an error. */
 const ERROR_ROW = `status = 'failed'`;
 
+/**
+ * The turn placeholder on rows recorded outside any AgentRun — failed and
+ * aborted auxiliary Host model calls (#5691). Such a row is honest accounting
+ * (real spend shape, unknown usage), so the ledger-wide coverage counts it.
+ * The value is a placeholder for the table's required turn column, not the
+ * settlement discriminator: rows carry a `no_run` column written by whichever
+ * seam recorded them, because a hosted execution legally named `auxiliary`
+ * owns rows under this same turn value (#5890 review). Shared with the writer
+ * so the placeholder cannot drift.
+ */
+export const NO_RUN_TURN_ID = 'auxiliary';
+
 export const TOKEN_SUMS = `
   SUM(COALESCE(input_tokens, 0)) AS input,
   SUM(COALESCE(output_tokens, 0)) AS output,
@@ -60,6 +72,19 @@ export const COVERAGE_SUMS = `
   SUM(usage_basis = 'partial') AS usagePartialAttempts,
   SUM(usage_basis = 'missing') AS usageMissingAttempts`;
 
+/**
+ * Coverage a hosted execution's settlement may hold a run to (#5691): the
+ * rows the run owns — the ones its Session's event-stream projection
+ * recorded, outside the `no_run` mark the usage-unknown seam writes. The
+ * ownership exclusion is the query's WHERE clause, not an aggregate here, so
+ * this stays narrower than the ledger-wide {@link COVERAGE_SUMS} on purpose:
+ * one answers "what does the ledger hold unknown-usage rows for", the other
+ * "what did this run leave unsettled".
+ */
+export const RUN_SETTLEMENT_COVERAGE_SUMS = `
+  SUM(usage_basis = 'partial') AS usagePartialAttempts,
+  SUM(usage_basis = 'missing') AS usageMissingAttempts`;
+
 export const REQUEST_SUMS = `
   COUNT(*) AS totalRequests,
   SUM(${PRICED_COST}) AS totalCostUsd,
diff --git a/packages/storage/src/sqlite-usage-schema.ts b/packages/storage/src/sqlite-usage-schema.ts
index cf796d75c7..c25b37bb22 100644
--- a/packages/storage/src/sqlite-usage-schema.ts
+++ b/packages/storage/src/sqlite-usage-schema.ts
@@ -19,7 +19,7 @@
 
 import type { DatabaseSync } from 'node:sqlite';
 
-export const SQLITE_USAGE_SCHEMA_VERSION = 9;
+export const SQLITE_USAGE_SCHEMA_VERSION = 10;
 
 /**
  * The canonical ledger's columns, in the order every statement binds them.
@@ -49,6 +49,7 @@ export const MODEL_CALL_COLUMNS = [
   'reasoning_tokens',
   'cost_basis',
   'cost_usd',
+  'no_run',
 ] as const;
 
 /**
@@ -140,6 +141,11 @@ const MODEL_CALL_TABLE = `
     reasoning_tokens INTEGER,
     cost_basis TEXT,
     cost_usd REAL,
+    -- Which writer recorded the row: the run's event-stream projection (0) or
+    -- the usage-unknown seam for calls no AgentRun owns (1). Settlement reads
+    -- this, not the turn value — a hosted execution legally named like the
+    -- no-run sentinel owns rows under the sentinel turn too (#5890 review).
+    no_run INTEGER NOT NULL DEFAULT 0,
     CHECK (${MODEL_CALL_REQUIRED_COLUMNS.map(
       (column) => `(${column} IS NULL) = (cost_basis IS NULL)`,
     ).join(' AND ')}),
@@ -221,6 +227,12 @@ export function migrateSqliteUsageDatabase(db: DatabaseSync): void {
   // through, and the conversion below reads one.
   ensureColumn(db, 'usage_model_call_attempts', 'session_id', 'TEXT');
   spreadModelCallRecordJson(db);
+  // no_run is written by the recorder, never inferred from the turn value:
+  // a backfill keyed on the auxiliary turn string would flip a legally named
+  // execution's own run-owned rows (see the settlement-coverage regression in
+  // model-call-usage-query.test.ts). Databases from before this column cannot
+  // hold auxiliary rows - recording them is what introduced the column.
+  ensureColumn(db, 'usage_model_call_attempts', 'no_run', 'INTEGER NOT NULL DEFAULT 0');
   db.exec(`
     CREATE INDEX IF NOT EXISTS usage_model_call_attempts_completed_at
       ON usage_model_call_attempts(completed_at DESC, attempt_id);
@@ -364,7 +376,10 @@ function spreadModelCallRecordJson(db: DatabaseSync): void {
       attempt_id,
       completed_at,
       session_id,
-      ${pricing}
+      ${pricing},
+      -- Pre-column rows all predate the usage-unknown seam: every one of them
+      -- was recorded by the run's event-stream projection.
+      0 AS no_run
     FROM classified;
 
     DROP TABLE usage_model_call_attempts_blob;
diff --git a/packages/storage/src/usage-stores.ts b/packages/storage/src/usage-stores.ts
index a92c9f5450..f0bf1b747b 100644
--- a/packages/storage/src/usage-stores.ts
+++ b/packages/storage/src/usage-stores.ts
@@ -41,6 +41,8 @@ import {
   ModelCallLedgerPublicationError,
   type ModelCallLedger,
   type ModelCallLedgerReader,
+  type RunSettlementCoverage,
+  type UsageUnknownModelCallRecord,
 } from './model-call-ledger.js';
 import {
   PricingCommitUnknownError,
@@ -127,12 +129,24 @@ export interface ModelCallIndexReader {
     offset: number,
     limit: number,
   ): Promise<ModelCallLedgerResult<ModelCallUsageLogs>>;
+  /**
+   * What the settlement window itself left unsettled (#5890) — what hosted
+   * execution settlement checks instead of the ledger-wide coverage, which
+   * must also count rows no run owns.
+   */
+  modelCallRunSettlementCoverage(from: number, to: number): Promise<RunSettlementCoverage>;
 }
 
 export interface ModelCallIndexWriter extends ModelCallIndexReader {
   catchUpModelCallProjection(
     input?: CatchUpModelCallProjectionInput,
   ): Promise<CatchUpModelCallProjectionResult>;
+  /**
+   * Records one usage-unknown row for a model call outside any AgentRun
+   * (#5691) — auxiliary Host calls the event stream cannot project. The owning
+   * Session, when known, is published after the write.
+   */
+  recordUsageUnknownAttempt(record: UsageUnknownModelCallRecord): Promise<void>;
 }
 
 export interface PricingAuthorityReader {
@@ -526,7 +540,13 @@ function createWriterFacade(
         read(() => modelCalls.buckets(query, groupBy, now)),
       modelCallLogs: (query, now, offset, limit) =>
         read(() => modelCalls.logs(query, now, offset, limit)),
+      modelCallRunSettlementCoverage: (from, to) =>
+        read(() => modelCalls.runSettlementCoverage(from, to)),
       catchUpModelCallProjection: admitModelCallProjectionCatchUp,
+      recordUsageUnknownAttempt: (record) =>
+        admitSessionUsageMutation(record.sessionId, () =>
+          modelCalls.recordUsageUnknownAttempt(record),
+        ),
     },
     pricing: {
       snapshot: () => read(() => pricing.snapshot()),
@@ -578,6 +598,8 @@ function modelCallReader(
       run(() => ledger.buckets(query, groupBy, now)),
     modelCallLogs: (query: UsageQuery, now: number, offset: number, limit: number) =>
       run(() => ledger.logs(query, now, offset, limit)),
+    modelCallRunSettlementCoverage: (from: number, to: number) =>
+      run(() => ledger.runSettlementCoverage(from, to)),
   });
 }
 


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org