feat(project): persist usage outside disposable OpenCode state - #118
Merged
Merged
Conversation
This was referenced Sep 1, 2026
jonasotoaguilar
marked this pull request as ready for review
September 1, 2026 05:26
…iest owning slice
…coverage at owning slice Restore deletion UPSERT test moved too early from durable-migration and wire browser fail-closed recovery on unavailable/malformed/truncated session data at its owning slice. fetchSessionsForBrowse now returns null on error/truncated/limit (BROWSER_SESSION_LIMIT) and loadBrowserProjects fail-closes with explicit throw, using durable checkpoints union (reconcileProjectUsage) so successful [] legitimately recovers checkpoint while null never synthesizes zero. Proof: browser-projects-failclosed and durable-deleted were failing (2 fail) before fix due to premature assertions without production; after fix 403/403 pass, durable/deleted.ts 98.9% line coverage.
…llback and test isolation
…iome suppressions Isolate TOKENMETER_DURABLE_DIR per mountEntry and per cost-fallback Unit 3 test so the shared global durable checkpoint file does not leak between tests. Without isolation the global checkpoints.sqlite is reused across concurrent mounts, causing project totals to include stale checkpoints and waitForFrameDriven to time out deterministically. Add biome-ignore-all for non-null assertions in harness tests and format long lines so biome:check passes at this slice instead of deferring broken tests to later PRs. Fixes render timeout failures (12) and cost-fallback B isolation (0.0725 vs 0.0125) on this PR's own CI.
…erage/biome Move db.ts to thin re-export of legacy-db so per-file coverage passes at this cutover bridge slice. TokenMeter still imports via db path. Sort project.ts imports and fix harness.test.ts organizeImports so biome:check passes without errors.
…ependence Restore hasLegacy bridge in project.ts at legacy-adapter so cost-fallback tombstone and render projectIDHint tests remain green while durable union is introduced. The durable-only cutover moves to the owning cost-fallback/harness slices where durable tests exist.
Migrate session.deleted handling from legacy SQLite aggregate (projectDbPath/recordDeletedSession) to durable per-session checkpoint (checkpointDeletedSession via durableDbPath + alias) and isolate the three affected harnesses with TOKENMETER_DURABLE_DIR temp fallback.
Remove legacy-db import from finalize slice and keep simple durable union (without observed-cost extension) so the slice independently passes typecheck/coverage/biome. Formatting fixes for cost-fallback coverage gates.
Project previously consumed only session.list aggregate cost, which is partial when subscription messages have zero cost; message-derived observed usage (per-message cost via usageOf, zero-cost estimated) was ignored, causing Project .23 vs Session $12.97 undercount. Add observed costSource, extend mergeCost/SQL to let observed replace smaller partial while keeping larger high-water, and merge observed entries for session IDs present in the successful project list before batch UPSERT and reconciliation (principal and delegated rows independently, one WAL transaction, no extra SDK calls). Existing low checkpoints heal monotonically; second unchanged refresh zero-ops; provenance survives SQLite readback.
chore(release): prepare v1.4.0
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🔗 Linked Issue
Closes #117
🏷️ PR Type
What kind of change does this PR introduce?
type:bug— Bug fix (non-breaking change that fixes an issue)type:feature— New feature (non-breaking change that adds functionality)type:docs— Documentation onlytype:refactor— Code refactoring (no functional changes)type:chore— Build, CI, or tooling changestype:breaking-change— Breaking change (fix or feature that changes existing behavior)📝 Summary
Durable per-session checkpoint integration tracker for #117. This tracker branch is the feature trunk for the chained delivery; it holds the integration contract (ADR-0009) and supersedes ADR-0006. All functional changes land via the child stack PRs that target this branch. The durable store moves Project history outside
api.state.path.stateso deleting the OpenCode cache no longer deletes history.📂 Changes
docs/adr/0009-durable-per-session-checkpoints.mddocs/adr/0006-sqlite-persistence-for-deleted-project-usage.mdChain Context
mainmain@45937c3Chain Overview
Chain Status
🧪 Test Plan
bun run typecheck bun test test/durable-paths.test.tsbun run typecheckon tracker — no errors)bun test389/389,bun run typecheck,bun run buildverified onfix/durable-project-observed-cost(fix(project): use observed message-derived cost for Project checkpoints #142)🤖 Automated Checks
The following checks run automatically on this PR:
additions + deletions) or use maintainer-appliedsize:exceptionCloses/Fixes/Resolves #N; child PR:Related to #Nstatus:approvedtype:*Labeltype:*label must be applied✅ Contributor Checklist
status:approvedsize:exceptionwith rationale documentedCloses #N, child PR usesRelated to #Nmaintype:*label to this PRCo-Authored-Bytrailers💬 Notes for Reviewers
Tracker is draft/no-merge until the full child stack (20 PRs) is reviewed and integrated. Review the child stack bottom→top; this PR only carries the ADR contract. Manual live canary pending on final top
feat/durable-docs— stack must remain draft untilbun test389/389,bun run typecheck,bun run build, andbiome checkare green on the top branch.