Skip to content

feat(cost): track OpenCode local history in the cost store (#4757) - #4786

Merged
steipete merged 7 commits into
mainfrom
triage/20260921-opencode-50-finish
Oct 26, 2026
Merged

steipete merged 7 commits into
mainfrom
triage/20260921-opencode-50-finish

Conversation

@steipete

Copy link
Copy Markdown
Owner

Finishes #4757 by @Danielweng0902, implementing the design approved in #4752: OpenCode's local history (opencode.db) feeds the existing cost-usage store as an opt-in source for the ambient Codex ledger.

This PR exists only because GitHub denies maintainer pushes to the contributor fork (Danielweng0902/Win-CodexBar is a fork of a fork, so "allow edits by maintainers" does not reach it). Daniel's four commits are preserved unchanged in this branch's history; the maintainer work is one commit on top plus a main merge.

What changed relative to #4757:

  • Persistence ownership: native full saves preserve adapter file rows and only update native aggregate contributions; same-path database replacement (path/device/inode/creation identity plus DB/WAL fingerprints) invalidates stale progress.
  • Bounded reconciliation: one resumable raw-row sweep with timestamp/rowid revision checkpoints, part continuations that survive small passes, each parent evaluated once per pass, a bounded ledger sweep for deleted upstream rows, and explicit legacy/v2 precedence.
  • Work budgets: raw rows are counted before eligibility filtering, payload length is checked before copying, and SQLite instruction/deadline handlers plus Task cancellation bound every pass. Fixed-budget runs over synthetic 1k/10k/100k histories stay flat (219 / 219 / 219 VM steps).
  • Publication: fresh, cached and catch-up views include the source only for the opted-in ambient ledger; explicit CODEX_HOME/session roots, managed accounts and Spend Dashboard are excluded; the adapter outcome drives completeness; buckets follow the reporting calendar; recorded $0 stays authoritative.
  • The contract diagnostics from the audit are committed as regression tests; the architecture gate, translations (22 catalogs), parser fingerprint (predecessor-compatible) and docs/opencode.md are updated.

Proof: focused performance/store/settings/gate suites (693 tests) and the merged-main integration run (286 tests) pass, make check passes, and an isolated Codex review through P2 is clean. PR CI is the broad gate.

Closes #4752.
Supersedes #4757.

Danielweng0902 and others added 5 commits October 24, 2026 14:52
Structural foundation for the #4752-approved adapter direction: a
versioned, backward-compatible source discriminator on the files
scan_state JSON (absent = native Codex, so upgrade needs no migration),
a typed versioned OpenCodeSourceCheckpoint payload for the adapter's
table windows, part continuation, updated-watermarks and reconciliation
progress, and source-aware restore dispatch so adapter records never
decode as Codex JSONL state. Tests cover the legacy-payload upgrade
path, checkpoint version gating, and a discriminated round trip through
upsert/readSnapshot.
Stage 1+2 of the #4752 checklist. The adapter decodes OpenCode assistant
turns inside short read-only source transactions and commits usage rows,
per-file day aggregates, global deltas and its typed checkpoint
atomically through applyOpenCodeLocalHistoryPass (baseline
revalidation, rollback on stale). Turns keep hash-stable identities
over <table>:<sourceID>; windows walk by exclusive rowid boundaries
pinned by their own SELECT with raw-lookahead exhaustion.

Explicit regressions for the three #4744 cursor failures: invalid rows
consume budget without starving older valid rows, oversized messages
checkpoint a strict (messageRowid, partRowid) continuation and resume
mid-message without re-emitting, and appends after a snapshot stay
eligible because boundaries never come from a later MAX(rowid). Tests:
5 adapter tests + 4 checkpoint seam tests, all passing.
Upstream UPDATEs rows in place while streaming, so the pass now walks
time_updated watermarks per table and re-evaluates the containing
message (or session row), replacing the prior contribution at the same
identity: old payloads resolve via the store's readUsagePayloads point
lookup, their negation folds into the global merge, and per-file
aggregates recompute as absolute stored+new-old values. A pure delete
(a session row that becomes excluded or invalid) removes its footprint.
Late step-finish parts swap the fallback row for the part. Tests:
covered-code mutation, late parts, and session updates all pass
(8 adapter tests total).
Stage 4 of the #4752 checklist. The adapter's contribution now lands in
the Codex daily report with provenance resolved at read time:

- sourceRecorded marker on ModelBreakdown (report-model case only, never
  persisted in store enums); merge keeps recorded and priced breakdowns
  of the same model apart via provenanceKey, so a recorded /bin/zsh
  subscription day can never fold into a same-named priced estimate.
- Recorded zero stays a PRESENT zero in costUSD — presence is the
  signal, per the recorded-cost-as-is contract.
- CostUsageStoreAccess.sharedScanStore gives the adapter the scanner's
  own shared store actor (one persistence owner); the pass runs in the
  fetcher's async seam beside the synchronous scan executor.
- Options.includeOpenCodeLocalHistory (default off) flows from
  SettingsStore.openCodeLocalHistoryEnabled through UsageStore into the
  fetcher; the ambient gate excludes any scan with an explicit
  codexSessionsRoot or CODEX_HOME override.
- Preferences toggle under the Codex provider detail.

Tests: 4 new stage-4 tests (recorded-/bin/zsh conversion + provenance, merge
keeps recorded/priced apart, ambient gate matrix, default-off). All 12
adapter tests pass; full-suite regressions are unrelated environment
clusters (keychain access absent in this shell, one keyboard-layout-
dependent shortcut test, load-timing flakes that pass in isolation).
Merge current main and finish the approved shared-store adapter. Preserve
native persistence ownership, recorded zero costs, source provenance, and
ambient-only publication. Reconcile updates and deletions with resumable
raw-row sweeps, bounded payload/page work, and cancellation.

Keep cached spend visible during partial window refreshes without turning
unknown token counts into zero. Add regression and scale coverage, native
parser compatibility, translations, documentation, and contributor credit.

Validation: 693 focused tests; 286 merged-main integration tests; 43 final
source tests; make check with zero lint violations. The focused source run
keeps SQL VM work flat across synthetic 1k/10k/100k histories.

Fixes #4752
Refs #4757
Co-authored-by: Daniel930902 <daniel0902life@gmail.com>
@clawsweeper

clawsweeper Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

ClawSweeper review complete

ClawSweeper finished reviewing this revision. The review result is being finalized.

View the workflow run.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-26T15:41:21.088297Z 9e17a90 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0723cce20b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +117 to +118
var isAssistant: Bool {
self.providerID == "openai" && self.role == "assistant"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Include v2 compaction requests in imported usage

When an OpenCode v2 database contains an OpenAI-backed session_message with type = 'compaction', this predicate rejects it even when it has valid recorded costs and tokens. decodeRow maps the table's type column into role, so these requests are silently omitted and the scan can still claim complete coverage. The existing OpenCodeGoLocalUsageReader.sessionMessageUsageSQL and OpenCodeGoV2LocalUsageReaderTests explicitly handle this same schema's compaction costs. Accept compaction records for the v2 source while retaining the assistant-only restriction for legacy messages.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added clawsweeper:intake:feature Preliminary submission classification; full source review pending. P2 Normal priority bug or improvement with limited blast radius. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed clawsweeper:intake:feature Preliminary submission classification; full source review pending. labels Oct 26, 2026
@clawsweeper

clawsweeper Bot commented Oct 26, 2026

Copy link
Copy Markdown

Codex review: blocked before merge.

What this changes

Adds optional OpenCode local usage ingestion into the existing ambient Codex cost ledger.

Example: Enable OpenCode local history with an OpenAI-backed request recording $0 in opencode.db.

  • Before: The request is absent from Codex local cost history.
  • After: The request contributes recorded spend of $0 without being repriced or assigned to a managed account.

Review scores

Measure Result What it means
Overall readiness 🦐 gold shrimp (3/6) Useful, explicitly approved work with substantial regression coverage, one confirmed accounting defect, and incomplete release-upgrade evidence.
Proof confidence 🦐 gold shrimp (3/6) Maintainer authorship exempts ordinary shipped-entry-point proof; the supplied validation exercises real adapter, store, fetcher, and settings paths in process. The persistence gate remains incomplete: predecessor-hash fixtures support compatibility, but no supplied v0.81.0-to-head upgrade run demonstrates existing settings, native rows, and unfinished checkpoints surviving together.
Patch quality 🦐 gold shrimp (3/6) 1 actionable review finding remain.

Product

Kind: Feature · Worth it: Yes · Fix scope: Complete
User problem: People using OpenCode with OpenAI cannot include that device's recorded usage in ambient Codex local cost history.
Reason: The owner explicitly approved the feature and its new default-off setting; this PR supplies the requested shared-store implementation.

Merge readiness

⛔ Blocked before merge - 2 items remain

Keep this maintainer-authored PR open: it implements an approved capability absent from main, but a correctness finding blocks a clean verdict.

Priority: P2
Reviewed head: 0723cce20bd032267df75e7161cf727b23953a54

Before merge

  • Include v2 compaction requests in imported usage (P2) - For an OpenAI-backed session_message with type='compaction' and valid recorded cost/tokens, decodeRow places the table's type in role, so this predicate rejects the row. advanceSource still advances past it and can finish with complete coverage, silently understating spend. The existing same-schema OpenCodeGo reader accepts assistant and compaction, with a regression for a $2 compaction request. Make eligibility namespace-aware so v2 compaction usage is included while legacy message filtering remains assistant-only, and add an adapter regression.
  • Add data-model compatibility proof - The review found that existing stored data may not work after upgrade. Show that existing data still loads and works with this change.

Findings

  • [P2] Include v2 compaction requests in imported usage — Sources/CodexBarCore/Providers/OpenCode/OpenCodeLocalHistoryAdapter.swift:117-118

Tests

  • Missing end-to-end proof: No supplied shipped-app upgrade run shows v0.81.0 settings, native history, and unfinished checkpoints remaining intact after enabling the new source.
Agent review details

How this fits together

The adapter reads OpenCode SQLite usage metadata, persists bounded reconciliation progress and contributions through CostUsageStore, and merges source-labelled totals into ambient Codex reports.

flowchart LR
  A[OpenCode database] --> B[Read only adapter]
  B --> C[Shared CostUsageStore]
  D[Native Codex scanner] --> C
  C --> E[Scoped read view]
  E --> F[Ambient Codex history]
Loading

Technical review

Best possible solution:

Land the approved adapter with complete supported v2 usage accounting and demonstrated preservation of existing release data.

Do we have a high-confidence way to reproduce the issue?

Source inspection shows that an OpenAI-backed v2 compaction row with recorded cost 2 is rejected before ingestion; no executable reproduction was run.

Is this the best way to solve the issue?

The owner-approved adapter appropriately reuses the existing persistence and read-view owners; its v2 eligibility filter needs a narrow correction.

Full review comments:

  • [P2] Include v2 compaction requests in imported usage — Sources/CodexBarCore/Providers/OpenCode/OpenCodeLocalHistoryAdapter.swift:117-118
    For an OpenAI-backed session_message with type='compaction' and valid recorded cost/tokens, decodeRow places the table's type in role, so this predicate rejects the row. advanceSource still advances past it and can finish with complete coverage, silently understating spend. The existing same-schema OpenCodeGo reader accepts assistant and compaction, with a regression for a $2 compaction request. Make eligibility namespace-aware so v2 compaction usage is included while legacy message filtering remains assistant-only, and add an adapter regression.
    Confidence: 0.98
    Late finding: first raised on code an earlier review cycle already covered.

Overall correctness: patch is incorrect
Overall confidence: 0.95

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning medium; reviewed against c3d8ca5d7a82.

Provenance checked

  • Shared SQLite persistence and native save ownership keeps the original intent (56a763e: The store foundation and subsequent SQLite cutover established one transactional owner for derived history; the adapter preserves that owner while isolating source-specific payloads.)
  • Read-view separation, streaming, and completion keeps the original intent (perf: narrow cached Codex cost reads #3250: Status/activity reads avoid detailed scanner state, and later work preserves snapshot consistency and validated-window publication; the new source summary extends those existing purposes.)
  • Report accumulation and estimate presentation changes intended behavior with a stated reason (Refactor duplicated Codex report accumulation and pricing #3479: Shared accumulation preserves nil-versus-zero pricing semantics; the approved source-recorded marker separates recorded dollars from native estimates.)
  • Documented OpenCode history exclusion changes intended behavior with a stated reason (docs: clarify OpenCode quota and cost boundaries #3274: Documentation distinguished remote quota from unsupported ordinary OpenCode history; the later owner-approved adapter intentionally changes that supported boundary.)

Testing

Proof path: in-process harness.

Security

None.

Evidence

Acceptance criteria:

  • make test-fast FILTER='OpenCodeLocalHistory'
  • make check
  • Verify the new compaction regression fails before the eligibility correction and passes afterward.

What I checked:

Likely related people:

  • Peter Steinberger: Raw commit 56a763e adds Sources/CodexBarCore/Vendored/CostUsage/CostUsageStore.swift:31 relative to its recorded parents. This identifies author metadata, not feature responsibility or a PR merger. (role: source-line author; confidence: high; commits: 56a763eaa34c; files: Sources/CodexBarCore/Vendored/CostUsage/CostUsageStore.swift)
  • kernnel: Raw commit 3c004ec adds Sources/CodexBarCore/Vendored/CostUsage/CostUsageStore+ReadView.swift:11 relative to its recorded parents. This identifies author metadata, not feature responsibility or a PR merger. (role: source-line author; confidence: medium; commits: 3c004ec2bfcb; files: Sources/CodexBarCore/Vendored/CostUsage/CostUsageStore+ReadView.swift)

Labels

Label changes:

  • add P2: This is an approved optional history feature with a bounded accounting defect, without an established urgent regression.
  • add rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦐 gold shrimp and patch quality is 🦐 gold shrimp.
  • add status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action.

Label justifications:

  • P2: This is an approved optional history feature with a bounded accounting defect, without an established urgent regression.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦐 gold shrimp and patch quality is 🦐 gold shrimp.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action.

Rating scale

6/6 🦀 challenger crab · 5/6 🦞 diamond lobster · 4/6 🐚 platinum hermit · 3/6 🦐 gold shrimp · 2/6 🦪 silver shellfish · 1/6 🧂 unranked krab. Overall follows the weaker of proof and patch quality; ✨ marks media proof (a screenshot, video, or linked artifact) that directly shows the changed behavior.

Workflow

ClawSweeper edits this one comment on every review. Comment @clawsweeper re-review for a fresh review only. Repair and merge execution lanes are retired.

Reviewed October 26, 2026, 9:53 AM ET / 13:53 UTC.

steipete added a commit that referenced this pull request Oct 26, 2026
@steipete
steipete merged commit 914204f into main Oct 26, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P2 Normal priority bug or improvement with limited blast radius. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Design sketch: OpenCode local history as a CostUsageStore source adapter (#3273)

2 participants