Skip to content

fix(accounting): credit monitor only after durable token commit - #4811

Open
ScriptedAlchemy wants to merge 9 commits into
masterfrom
fix/4447-monitor-committed-savings
Open

ScriptedAlchemy wants to merge 9 commits into
masterfrom
fix/4447-monitor-committed-savings

Conversation

@ScriptedAlchemy

@ScriptedAlchemy ScriptedAlchemy commented Nov 8, 2026 •

Copy link
Copy Markdown
Owner

Scope — Refs #4447 (correctness slice, not full acceptance)

The canonical project-store writer already atomically commits lifetime and resettable savings counters. However the MCP accounting task wrote a positive saved-token delta to the live monitor ring even when the project-store commit refused, so terminal-monitor totals could claim savings that were never durable. The logged persistence error did not stop that credit.

This one-file change makes commit_token_savings report whether the project-store transaction committed. The monitor always retains the raw tool-activity size; it publishes a positive saved-token delta only for a successful canonical commit. Optional global projection failure remains warned and does not erase a locally committed saving. The response remains nonblocking and observed ledger-write shutdown settlement is unchanged. No schema, lock, API, dashboard, policy or release changes.

Falsifiable production regression

The new live_monitor_reports_only_committed_token_savings Rust test uses a registered project store plus the real memory-mapped monitor ring, not mock counters: a successful 7-token response must appear as delta 7 with raw input 20, then a committed maximum counter forces the next 1-token write to fail checked addition. Its monitor activity must still appear with raw input 30 but delta 0, and both durable project counters must remain unchanged at the boundary. The old implementation fails the delta-0 assertion. Existing concurrent/restart/rollback tests remain intact.

Review / validation

Commit 109f4608e616 is a single-parent change based on master 91c72aba7750, touching only crates/tracedecay/src/mcp/server/ledger.rs (88 added / 5 removed). Diff reviewed; pushed with force=false and exact expected-old-head fast-forward. No existing #4447 branch was rewritten.

Not yet verified by Bazel: this connector-backed runtime has no local checked-out repository or Bazel installation. Hosted CI for the exact head must execute a nonzero Rust //crates/tracedecay:unit_test (including this module's test) and //crates/tracedecay:automation_runner_test, plus format/Clippy and relevant native macOS verification. No CI pass is claimed before job logs establish execution.

Remaining #4447: durable per-response idempotency/replay identity across retries, explicit failed-stage diagnostics and reinsertion/restart/disconnect coverage, proving no double credit under all races, and reducing duplicate authority. Those are not satisfied by this monitor fix; keep #4447 open, Refs only. PR-maintenance handles CI review and eligible merges; no automatic merge on green metadata. Mixed Kev/draft #4776 and release #4763 untouched.

Latest CI source fix — hosted Rustfmt (2026-11-08)

Commit 48d27c89 applies all three exact formatting corrections in ledger.rs reported by Repository gates run 42453927974: one awaited-commit conditional and two multi-line counter assertions. Diff independently reviewed: one file, twelve insertions/three deletions, no behavior or assertion changes. Published with force=false and expected previous head. New-head Bazel/MCP integration remains unverified; no test pass or #4447 completion is claimed. Remaining durable response idempotency and reset/replay integration must still be addressed.

Keep the live monitor's raw tool activity after a local accounting
write fails, but publish zero saved tokens instead of crediting the
uncommitted delta. Only the canonical project-store commit controls
what the monitor reports; optional global projection remains best-effort.

Add a real registered-store and mmap-backed regression covering
successful savings, an overflow refusal, both durable counters and
monitor output. No schema, release or policy changes.

Refs #4447
@changeset-bot

changeset-bot Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 8c96a27

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Apply the exact source changes requested by the first failing hosted
Bazel Rustfmt gate at the preceding PR head. No behavior or assertions
change; all existing regression tests are preserved.

Refs #4447

Verification: source contexts checked against hosted Rustfmt diffs.
New-head Rust/Bazel tests require hosted CI.

@devin-ai-integration devin-ai-integration Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Newer findings are available below. Devin Review posted a newer report on this PR, in addition to the findings presented here.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

Repair three hosted automation_runner_test failures by supplying the
configured executable identity required by the production prefilter.
Use the same identity for the prefilter and retained runner, preserving
manual-schedule, exact-ledger, live-lock and lock-race assertions.

Add a production-prefilter regression for unconfigured refusal,
deduplication and same-occurrence recovery after binding, with zero
backend calls and no effectful terminal. Do not relax backend admission,
change timeouts, or alter the graph publication changes.

Refs #4532
devin-ai-integration[bot]

This comment was marked as resolved.

A synchronous OnceLock wait inside the asynchronous historical-ingest
fixture blocked the worker that must poll live projection concurrently.
Use a durable async watch latch to preserve release ordering while
exercising the real interleaving and supersession journey.

Refs #4481

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant