Skip to content

fix(antigravity): skip steps without stepUUID during token scan - #3451

Closed
horosin wants to merge 3 commits into
steipete:mainfrom
horosin:fix/antigravity-step-uuid-withholding
Closed

fix(antigravity): skip steps without stepUUID during token scan#3451
horosin wants to merge 3 commits into
steipete:mainfrom
horosin:fix/antigravity-step-uuid-withholding

Conversation

@horosin

@horosin horosin commented Sep 6, 2026

Copy link
Copy Markdown

Summary

I've been wanting to see Antigravity usage and cost tracking in CodexBar work just like Codex does. I saw the recent improvements in #3403 to fix token counts and the ongoing work in #3412 to pull dollar amounts. However, on my machine, local Antigravity token counts were still not showing up at all, withholding with:

Antigravity Token History
Local token history is unavailable or incomplete.
Local token history · dollar costs unavailable

In anticipation of full Antigravity cost support landing, I dug into why token history was still withheld and found a false-positive check during SQLite step scanning that this PR fixes.

Problem

In readStepTimestamps (Sources/CodexBarCore/Providers/Antigravity/AntigravityLocalSQLite.swift), encountering a row in the steps table without a stepUUID set rowsAreValid = false.

Antigravity legitimately logs non-conversational steps in its SQLite steps table (such as internal lifecycle markers, model config transitions, or auxiliary events). These records have timestamp fields (field 1) and step types (field 3), but omit field 12 (stepUUID) because they are not LLM turns.

When readStepTimestamps encounters any such step row without a stepUUID:

  1. It flags rowsAreValid = false.
  2. stepScan.isComplete evaluates to false.
  3. The database is marked isComplete = false.
  4. Because result.isComplete across all historical databases is an aggregate boolean AND, a single auxiliary step in any conversation database cascades to invalidate all databases across the entire machine, completely withholding token history.

Solution

  • Skip steps table rows without a stepUUID instead of invalidating the entire database scan.
  • Generation rows in gen_metadata that actually depend on external step timestamps remain fully protected by the existing recoveredCount < rows.pendingTimestampRows.count check.
  • Track botID ambiguity before skipping UUID-less rows: if an auxiliary step row carries a botID but lacks a stepUUID or timestamp, it is recorded as ambiguous so it cannot be mistakenly used as exact timestamp evidence.
  • Added regression test with synthetic auxiliary step bytes matching production traces ([0x0A, 0x0C, 0x08, 0xA7, 0x8C, 0xE6, 0xD4, 0x06, 0x10, 0xC0, 0xD5, 0xA0, 0xCB, 0x03, 0x18, 0x05, 0xD2, 0x01, 0x00]), and tests for duplicate bot IDs on UUID-less rows in either row order.
  • Updated documentation in docs/antigravity.md and CHANGELOG.md.

Real Behavior Proof

Before Fix

Token history was withheld across the entire machine with coverage marked incomplete:

Antigravity Token History
Local token history is unavailable or incomplete.
Local token history · dollar costs unavailable

After Fix

Local SQLite scan recovers full token history across all conversations:

➜  CodexBar git:(fix/antigravity-step-uuid-withholding) swift run CodexBarCLI cost --provider antigravity
[1/1] Planning build
Building for debugging...
[5/5] Emitting module CodexBarCLI
Build of product 'CodexBarCLI' complete! (8.86s)
Antigravity Token History
Today: 73M tokens
Last 30 days: 1.1B tokens
Local token history · dollar costs unavailable

Validation

swift test --filter AntigravityLocalReaderTests
swift test --filter AntigravityBotIDValidationTests
swift test --filter Antigravity
make check

All 403 Antigravity-focused tests and make check (SwiftFormat, SwiftLint, Oxlint) pass cleanly.

Skip auxiliary and lifecycle steps lacking a stepUUID in the steps table rather than invalidating the entire database scan.

Antigravity logs non-conversational steps (e.g., lifecycle markers, auxiliary status transitions) in its SQLite steps table that omit field 12 (stepUUID). Previously, encountering any row lacking a stepUUID flagged rowsAreValid = false, which cascaded to make the entire multi-database token scan incomplete and completely withheld local token history.

Generation rows requiring step timestamps remain protected by checking recoveredCount against pendingTimestampRows.count. Added regression tests verifying that rows without stepUUID are safely skipped while preserving full coverage.
@clawsweeper

clawsweeper Bot commented Sep 6, 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.

@clawsweeper clawsweeper Bot added P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 other 🚨 Merging this PR has meaningful risk outside the owned taxonomy. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Sep 6, 2026
@clawsweeper

clawsweeper Bot commented Sep 6, 2026

Copy link
Copy Markdown

Codex review: needs maintainer review before merge. Reviewed September 6, 2026, 4:36 PM ET / 20:36 UTC.

ClawSweeper review

What this changes

Skip Antigravity auxiliary SQLite steps without a step UUID while preserving conflicting bot-ID evidence, with regression tests and documentation updates.

Merge readiness

Ready for maintainer review

This remains a useful, focused fix: current main and v0.56.7 still reject UUID-less steps. The earlier bot-ID conflict finding is resolved, the supplied CLI proof demonstrates restored history, and no new blocking defect was found.

Priority: P2
Reviewed head: e305c32673e9ef74d42c72e4dcc631778070676f

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) A focused repair with relevant real CLI output, targeted regressions, and the prior conflict-handling defect resolved.
Proof confidence 🐚 platinum hermit (4/6) Sufficient (terminal): The supplied rebuilt CLI run exercises the local SQLite reader through cost --provider antigravity and changes unavailable history into displayed daily and 30-day totals; relevant production code is unchanged since that proof-bearing review.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Verified Sufficient (terminal): The supplied rebuilt CLI run exercises the local SQLite reader through cost --provider antigravity and changes unavailable history into displayed daily and 30-day totals; relevant production code is unchanged since that proof-bearing review.
Evidence reviewed 10 items Applicable repository policy: Read the complete root AGENTS.md and checked Sources, Tests, docs, and .agents for nested instructions; none were found. No .agents/maintainer-notes directory exists. Applied the focused-parser-test, CLI-proof, and provider-isolation guidance.
Current main still contains the defect: The missing-or-empty stepUUID guard sets rowsAreValid to false. Database completeness is combined across databases, so an auxiliary row can withhold otherwise recoverable history.
Latest release remains affected: The same invalidating UUID guard is present in v0.56.7; this change is not already supplied by that release.
Findings None None.
Security None None.

How this fits together

CodexBar reads Antigravity’s local conversation databases and recovers timestamps for token usage. Scan completeness determines whether the CLI and app can display token history.

flowchart TD
  A[Local conversation databases] --> B[Read generation usage]
  B --> C[Recover missing timestamps from steps]
  C --> D[Preserve conflicting identity evidence]
  D --> E[Skip UUID-less auxiliary steps]
  E --> F{History complete?}
  F -->|Yes| G[Display token totals]
  F -->|No| H[Withhold incomplete history]
Loading

Before merge

None.

Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Production and test delta Production +8/-7 (net +1); tests +54/-6 (net +48) The small reader adjustment is supported by focused coverage for auxiliary rows and conflicting identities.

Technical review

Best possible solution:

Retain the narrow auxiliary-row tolerance while continuing to withhold unresolved generations and contradictory timestamp evidence.

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

Yes: current main rejects a valid UUID-less step whenever generation timestamps require the steps scan, propagating incomplete coverage. The contributor supplies before/after CLI output; this review did not execute a reproduction.

Is this the best way to solve the issue?

Yes: the patch adjusts the auxiliary-row guard within the existing reader and preserves ambiguity handling, avoiding a parallel parser or fallback path.

AGENTS.md: found and applied where relevant.

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

Labels

Label justifications:

  • P2: Repairs unavailable Antigravity local token history with a bounded provider-specific change.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The supplied rebuilt CLI run exercises the local SQLite reader through cost --provider antigravity and changes unavailable history into displayed daily and 30-day totals; relevant production code is unchanged since that proof-bearing review.
  • proof: sufficient: Contributor real behavior proof is sufficient. The supplied rebuilt CLI run exercises the local SQLite reader through cost --provider antigravity and changes unavailable history into displayed daily and 30-day totals; relevant production code is unchanged since that proof-bearing review.

Evidence

What I checked:

  • Applicable repository policy: Read the complete root AGENTS.md and checked Sources, Tests, docs, and .agents for nested instructions; none were found. No .agents/maintainer-notes directory exists. Applied the focused-parser-test, CLI-proof, and provider-isolation guidance. (AGENTS.md:1, e305c32673e9)
  • Current main still contains the defect: The missing-or-empty stepUUID guard sets rowsAreValid to false. Database completeness is combined across databases, so an auxiliary row can withhold otherwise recoverable history. (Sources/CodexBarCore/Providers/Antigravity/AntigravityLocalSQLite.swift:334, 7353c717502d)
  • Latest release remains affected: The same invalidating UUID guard is present in v0.56.7; this change is not already supplied by that release. (Sources/CodexBarCore/Providers/Antigravity/AntigravityLocalSQLite.swift:334, d8f4cec19b82)
  • Recovery safeguards retained: Read the complete SQLite reader. Bot-ID evidence is recorded before skipping UUID-less rows; missing UUIDs or timestamps invalidate exact evidence. Ambiguous positional slots, malformed payload rejection, resource budgets, and the pending-generation recovery-count check remain intact. (Sources/CodexBarCore/Providers/Antigravity/AntigravityLocalSQLite.swift:334, e305c32673e9)
  • Prior finding resolved and review continuity checked: The added parameterized test covers UUID-less duplicate bot IDs with and without timestamps in either row order. The relevant production, test, and documentation files are unchanged from the previously reviewed 28af6d3 head; the latest commit merges main. (Tests/CodexBarTests/AntigravityBotIDValidationTests.swift:163, e305c32673e9)
  • Real CLI proof exercises the changed path: The complete supplied PR body, captured under sourceRevision a733e6b91a9e5a80b634b5424ee3d48b900082257d69113a836bcc70541b22d4, shows unavailable history before the fix and a rebuilt CodexBarCLI cost --provider antigravity run reporting 73M tokens today and 1.1B over 30 days afterward. The inspected fetcher and CLI rendering path connect those results to SQLite scan completeness. The contributor also reports 403 focused tests and make check passing; this read-only review did not execute tests. (Sources/CodexBarCLI/CLICostCommand.swift:216, e305c32673e9)

Likely related people:

  • WeGoToMars: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)
  • Peter Steinberger: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

History

Review history (3 earlier review cycles)
  • reviewed 2026-09-06T18:47:46.712Z sha 26a8d96 :: needs real behavior proof before merge. :: [P2] Preserve bot-ID conflicts before skipping UUID-less rows
  • reviewed 2026-09-06T19:11:42.091Z sha 28af6d3 :: needs maintainer review before merge. :: none
  • reviewed 2026-09-06T19:23:59.838Z sha 28af6d3 :: needs maintainer review before merge. :: none

Record botID ambiguity before skipping steps that lack a stepUUID.

If an auxiliary step row carries a botID but lacks a stepUUID or timestamp, record it as ambiguous so it cannot later be used as exact timestamp evidence. Add regression tests validating that UUID-less step rows with duplicate botIDs invalidate exact evidence in either row order.
@horosin

horosin commented Sep 6, 2026

Copy link
Copy Markdown
Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Sep 6, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event exact_review_queue).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

@clawsweeper clawsweeper Bot added proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. merge-risk: 🚨 other 🚨 Merging this PR has meaningful risk outside the owned taxonomy. labels Sep 6, 2026

@steipete steipete left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

The bot-ID ordering fix addresses the earlier finding, and the rebuilt CLI output is useful availability proof. One date-attribution boundary still needs to be established before landing this skip.

parseStepMetadata does not identify a lifecycle step type. The new guard skips every syntactically valid record without a UUID, including the unknown-field-only record in the existing regression. With two pending generations sharing a UUID, one identified step timestamp, and one unidentified occurrence, skipping the latter leaves the single-timestamp fallback free to assign the identified timestamp to both generations. recoveredCount still reaches the expected count, so it does not prove that attribution was valid. The changed regression now explicitly accepts that case.

Please restrict the skip to positively identified auxiliary records while preserving unidentified occurrence evidence, or provide a producer contract establishing that UUID-less records cannot represent relevant generation occurrences. Keep coverage for unknown-field-only and timestamp-bearing unidentified records alongside the harmless lifecycle fixture. Restored total token counts alone do not verify the dates assigned to those generations.

Reviewed head: e305c32673e9ef74d42c72e4dcc631778070676f. This is a source/test-contract concern; I am not claiming to have inspected the private history used in the CLI demonstration.

steipete pushed a commit that referenced this pull request Sep 7, 2026
…#3462)

Antigravity bookkeeping rows without a step UUID caused the entire local history provider to be withheld as incomplete. Permit those rows after charging their row and byte budgets, while keeping malformed data and exhausted budgets as hard failures. A lone identified timestamp cannot stand for every occurrence of a reused UUID when unidentified rows are present.

Rows without UUIDs can still carry bot identity. Record that evidence before skipping UUID positioning: a duplicate bot ID with unknown UUID permanently invalidates exact and positional matches, regardless of scan order, matching timestamps, or absent timestamps. This addresses the review finding on the original revision. Keep ambiguous positional slots intact so later timestamps never move into them.

Share the identical step-occurrence structs, remove an unused counts projection, and apply positional ambiguity during timestamp selection. The final PR reduces production code by four lines. Token counts, pricing, credentials, discovery roots, and stored data remain unchanged. Changelog and documentation are updated; thanks @urda.

Maintainer validation: six synthetic duplicate-bot combinations failed 18 assertions on the original PR and pass after repair. All 406 focused Antigravity tests across 34 suites pass, including harmless bookkeeping, reused UUIDs, embedded timestamps, malformed rows, and budgets. `make check` passes and independent review is clean. The full `make test` suite passed all 1,028 selections across 86 groups without retries. The main integration preserves the tested Antigravity source, tests, and documentation byte-for-byte; integration `make check` also passes. Exact-head CI must pass before merge.

Contributor live evidence, collected on the original proposal: @urda compared the shipped 0.56.6 CLI and a rebuilt CLI against the same 211 stable local session databases from agy 1.1.27, using read-only scratch copies with WAL sidecars. Complete coverage increased from 208 to 211; the three recovered sessions contained 80,067, 48,183, and 5,299,395 tokens. Removing UUID-less bookkeeping rows from copies also made the shipped CLI return complete coverage, isolating the original cause. One previously passing session's output, excluding updatedAt, matched byte-for-byte. Three actively written sessions were excluded because both binaries reported them incomplete until checkpointing. This is contributor-reported live evidence; the maintainer's final ambiguity repair uses synthetic native SQLite fixtures.

This builds on #3266, #3396, and #3403. It is distinct from #3412's cost-estimation changes. Earlier proposal #3451 remains related; no unrelated issue is claimed resolved.

Co-authored-by: Peter Urda <peter.urda@gmail.com>
@steipete

steipete commented Sep 7, 2026

Copy link
Copy Markdown
Owner

Thanks @horosin for identifying this and providing the live CLI trace. The reported UUID-less bookkeeping-row failure and bot-ID ambiguity handling are now addressed on main by #3462 (a1391fc).

The landed fix also retains ambiguous positional slots and withholds shared timestamps for reused UUIDs when unidentified rows leave the evidence incomplete. It passed 406 focused Antigravity tests, the full suite, and CI. I compared this PR's final diff with that implementation; closing this overlapping proposal in favor of the landed fix.

@steipete steipete closed this Sep 7, 2026
@horosin

horosin commented Sep 7, 2026

Copy link
Copy Markdown
Author

Thank you @steipete! Really appreciate active maintaining of the project

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. proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants