feat(observability): capture every miner AI generation, and stop fabricating zero token counts - #10233
Merged
Merged
Conversation
added 2 commits
July 31, 2026 06:22
…Exempt field #10160 added linkedIssueMaintainerExempt to the repository-settings surface without regenerating packages/loopover-contract/src/api-schemas.ts, so contract:api-schemas:check has been failing on main since. The check is part of the local test:ci aggregate but is not wired into ci.yml, which is why nothing surfaced it. Pure regeneration: the one added line is the generator's own output for a field that already exists everywhere else.
Contributor
|
Important 🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨 ⏳ LoopOver is waiting…LoopOver has seen this pull request and is waiting on CI checks to finish before reviewing it. This comment will update once the review runs. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed · 🟨 Waiting |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
loopover-ui | 26afd39 | Commit Preview URL Branch Preview URL |
Jul 31 2026, 01:31 PM |
Contributor
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #10233 +/- ##
==========================================
+ Coverage 92.22% 92.25% +0.02%
==========================================
Files 937 938 +1
Lines 114413 114642 +229
Branches 27662 27680 +18
==========================================
+ Hits 105520 105758 +238
+ Misses 7588 7579 -9
Partials 1305 1305
Flags with carried forward coverage won't be shown. Click here to find out more.
|
This was referenced Jul 31, 2026
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.
Summary
Two AI-observability defects in one place: generations that were never reported, and token counts that were reported when nothing had been measured.
1. Every miner AI generation is now captured (#10200)
withCodingAgentAiGenerationCapturewas attached at one of the two driver construction sites — insideconstructProductionCodingAgentDriver.runCodingAgentAttemptbuilds its driver throughcreateCodingAgentDriverdirectly, so it never passed through that site and every attempt it ran was uncaptured, silently.runChatGroundingdrives a fullquery()session with a real turn budget and was never instrumented at all — it read only theassistant/usermessages it turns into wire events, so the SDK's ownresultframe, carrying the session's usage and cost, was on the wire and thrown away.Both are the shape #10170 catalogues: two or more places that must agree, with nothing enforcing it. Fixed the way #10127 fixed its own instance — make the bypass unrepresentable rather than document it:
packages/loopover-engine/src/miner/ai-generation-sink.ts) keepsposthog-nodeout of the portable engine package while letting the engine emit.initMinerPostHogregisters it only on the opt-in path, so the no-phone-home default (docs(selfhost): add combined ORB + AMS quickstart #6011) holds by construction.createCodingAgentDriver, the one chokepoint every real driver is built through. A future third construction site cannot opt out, because there is nothing left for it to forget to attach.runChatGroundingnow folds theresultframe and reports model/provider/latency plus real tokens and cost, on both the completed and the thrown path.noop, injected test drivers, and dry-run/paused attempts are deliberately not captured: none reaches a model, so an event there would fabricate a generation that never happened.2. No fabricated zero token counts (#10207)
capturePostHogAiGeneration(ORB) andcaptureMinerPostHogAiGeneration(miner) both did:so a provider that reported nothing contributed a
0PostHog cannot tell apart from a measured one — dragging every tokens-per-call and input:output ratio toward zero.$ai_total_cost_usdalongside them has always been conditional for exactly this reason; these two were the outliers. Now omitted when absent, and a genuinely measured0still lands, because absence is what is tested, not falsiness.Verified against the Orb rather than assumed, which corrects this issue's own open question. #10207 listed two candidate mechanisms and asked which applied.
ai_usage_eventson edge-nl-01 over 24h shows real per-call splits for the providers that carry the volume:So mechanism 1 ("providers genuinely report none") is false for those — the ORB had the numbers all along, and the PostHog nulls were the scrubber (#10211/#10212). The fabricated zeros were coming from the handful that really do report nothing (the Workers AI rows), and were being averaged in as if they were measurements. That is what this half fixes.
Deliberate deviation from one deliverable
#10200 asks that a chat-grounding provider-config error be visible as telemetry. It is not emitted here: no model is ever reached on that path, so an
$ai_generationwould fabricate spend — the same rule the other half of this PR enforces. That case is a request that produced no generation, which the ORB side gives its own separateselfhost_ai_degradedevent (#10186); the miner has no counterpart yet. Called out rather than quietly dropped, and pinned by a test.Also in this PR
One commit regenerating
packages/loopover-contract/src/api-schemas.ts. #10160 addedlinkedIssueMaintainerExemptwithout regenerating it, socontract:api-schemas:checkhas been failing onmainsince — it is in the localtest:ciaggregate but not wired intoci.yml, which is why nothing surfaced it.Closes #10200
Closes #10207
Scope
type(scope): short summaryConventional Commit format, for examplefix(api): restore profile access checks.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Closes #123) — a linked open issue is required for every contributor PR.Validation
git diff --checknpm run actionlintnpm run typechecknpm run test:coveragelocally;codecov/patchrequires ≥99% coverage of the lines AND branches you changednpm run test:workersnpm run build:mcpnpm run test:mcp-packnpm run ui:openapi:checknpm run ui:lintnpm run ui:typechecknpm run ui:buildnpm audit --audit-level=moderateDetail on what was run:
@loopover/engine's own node:test suite: 955 passed, 0 failed.ai-generation-sink.ts(13/13, 4/4),driver-factory.ts(57/57, 61/61),chat-grounding.ts(89/89, 91/91),agent-sdk-driver.ts(53/53, 64/64),loopover-miner/lib/posthog.ts(42/42, 45/45),coding-agent-construction.ts(23/23, 15/15).src/selfhost/posthog.tsis 174/174 lines with one uncovered branch at line 95 — pre-existing and outside this diff.runCodingAgentAttemptregression test; capturingnoopfails its own test.test/unit/**(vitest) andpackages/loopover-engine/test/**(node:test) — since only the second behavior-tests the package.test:engine-parity,test:driver-parity,test:live-gate-parity,test:miner-pack,build:miner, and the full drift sweep (db:migrations:check,db:schema-drift:check,selfhost:env-reference:check,miner:env-reference:check,cf-typegen:check,docs:drift-check,coverage-boltons:check,dead-exports:check,manifest:drift-check,engine-parity:drift-check,contract:api-schemas:check).npm auditreports 13 pre-existing advisories, all transitive underrelease-please/code-suggesterand unchanged by this PR — the diff adds zero dependencies (package.json/package-lock.jsonuntouched).Safety
UI Evidencesection below with JPG/JPEG or PNG screenshots arranged as organized, captioned, clickable thumbnails.Metadata-only, unchanged. No prompt, transcript, diff or tool output reaches any event added here — the chat-grounding capture reads the
resultframe's usage and cost and nothing else, and the result frame is never re-emitted as a wire event. The privacy boundary this endpoint enforces (tool allowlist,PUBLIC_FIELD_BLOCKLISTredaction on text and tool output) is untouched. The opt-in posture is likewise unchanged: no sink is registered unless the operator set their own PostHog key.UI Evidence
Not applicable — no visible UI, frontend, docs, or extension change.
Notes
runChatGroundingandrunCodingAgentAttempthave no production call site today — chat grounding is built for the miner-ui chat rail (#6517, still epic work under #9184/#9191), and the iterate loop consumes a driver fromconstructProductionCodingAgentDriverinstead. So this fixes latent blindness, not a live gap in current spend reporting. The value is structural: the capture is now attached where it cannot be bypassed, so those surfaces are already instrumented when they are wired, rather than shipping dark and being noticed later.