[{"data":1,"prerenderedAt":905},["ShallowReactive",2],{"navigation_docs":3,"-docs-metrics-metrics-pipeline":158,"-docs-metrics-metrics-pipeline-surround":900},[4,15,74,98,113],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":6},"Getting Started",false,"\u002Fdocs\u002Fgetting-started","docs\u002F1.getting-started",[10],{"title":11,"path":12,"stem":13,"icon":14},"Zeeq Introduction","\u002Fdocs\u002Fgetting-started\u002Fintroduction","docs\u002F1.getting-started\u002F1.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"children":19,"page":6},"Key Features","\u002Fdocs\u002Fkey-features","docs\u002F3.key-features",[20,25,30,35,40,45,50,55,59,64,69],{"title":21,"path":22,"stem":23,"icon":24},"Membership Invitations","\u002Fdocs\u002Fkey-features\u002Fmembership-invitations","docs\u002F3.key-features\u002F1.membership-invitations","i-hugeicons-cube",{"title":26,"path":27,"stem":28,"icon":29},"Command Palette","\u002Fdocs\u002Fkey-features\u002Fcommand-palette","docs\u002F3.key-features\u002F10.command-palette","i-hugeicons-search-01",{"title":31,"path":32,"stem":33,"icon":34},"Library Import and Export","\u002Fdocs\u002Fkey-features\u002Flibrary-import-export","docs\u002F3.key-features\u002F11.library-import-export","i-lucide-package-open",{"title":36,"path":37,"stem":38,"icon":39},"LLM Settings Configuration","\u002Fdocs\u002Fkey-features\u002Fllm-settings-configuration","docs\u002F3.key-features\u002F2.llm-settings-configuration","i-hugeicons-ai-magic",{"title":41,"path":42,"stem":43,"icon":44},"Agent Code Review Findings","\u002Fdocs\u002Fkey-features\u002Fagent-code-review-findings","docs\u002F3.key-features\u002F3.agent-code-review-findings","i-lucide-list-checks",{"title":46,"path":47,"stem":48,"icon":49},"Credentials & API Tokens","\u002Fdocs\u002Fkey-features\u002Fcredentials","docs\u002F3.key-features\u002F4.credentials","i-hugeicons-key-01",{"title":51,"path":52,"stem":53,"icon":54},"Manual Document Libraries","\u002Fdocs\u002Fkey-features\u002Fmanual-document-libraries","docs\u002F3.key-features\u002F5.manual-document-libraries","i-lucide-library-big",{"title":56,"path":57,"stem":58,"icon":29},"Snippet Search","\u002Fdocs\u002Fkey-features\u002Fsnippet-search","docs\u002F3.key-features\u002F6.snippet-search",{"title":60,"path":61,"stem":62,"icon":63},"Shared Prompt Fragment","\u002Fdocs\u002Fkey-features\u002Fshared-prompt-fragment","docs\u002F3.key-features\u002F7.shared-prompt-fragment","i-lucide-notebook-pen",{"title":65,"path":66,"stem":67,"icon":68},"Code Review Sources & Telemetry","\u002Fdocs\u002Fkey-features\u002Fcode-review-sources","docs\u002F3.key-features\u002F8.code-review-sources","i-hugeicons-book-01",{"title":70,"path":71,"stem":72,"icon":73},"Excluding Documents from Code Reviews","\u002Fdocs\u002Fkey-features\u002Fcode-review-document-exclusion","docs\u002F3.key-features\u002F9.code-review-document-exclusion","i-lucide-eye-off",{"title":75,"path":76,"stem":77,"children":78,"page":6},"Runtime Configuration","\u002Fdocs\u002Fconfiguration","docs\u002F5.configuration",[79,84,89,93],{"title":80,"path":81,"stem":82,"icon":83},"Google Cloud Configuration","\u002Fdocs\u002Fconfiguration\u002Fgcp-runtime","docs\u002F5.configuration\u002F1.gcp-runtime","i-hugeicons-google",{"title":85,"path":86,"stem":87,"icon":88},"GitHub Configuration","\u002Fdocs\u002Fconfiguration\u002Fgithub-configuration","docs\u002F5.configuration\u002F2.github-configuration","i-hugeicons-github",{"title":90,"path":91,"stem":92},"Local OpenIddict Certificates","\u002Fdocs\u002Fconfiguration\u002Flocal-openiddict-certificates","docs\u002F5.configuration\u002F3.local-openiddict-certificates",{"title":94,"path":95,"stem":96,"icon":97},"System Admin Access","\u002Fdocs\u002Fconfiguration\u002Fsystem-admin-access","docs\u002F5.configuration\u002F4.system-admin-access","i-hugeicons-shield-01",{"title":99,"path":100,"stem":101,"children":102,"page":6},"Metrics","\u002Fdocs\u002Fmetrics","docs\u002F6.metrics",[103,108],{"title":104,"path":105,"stem":106,"icon":107},"Metrics Dashboard","\u002Fdocs\u002Fmetrics\u002Fmetrics-dashboard","docs\u002F6.metrics\u002F1.metrics-dashboard","i-hugeicons-analytics-01",{"title":109,"path":110,"stem":111,"icon":112},"Metrics Pipeline","\u002Fdocs\u002Fmetrics\u002Fmetrics-pipeline","docs\u002F6.metrics\u002F2.metrics-pipeline","i-hugeicons-database-02",{"title":114,"path":115,"stem":116,"children":117,"page":6},"Design and Architecture","\u002Fdocs\u002Farchitecture","docs\u002F9.architecture",[118,123,128,133,137,141,145,150,154],{"title":119,"path":120,"stem":121,"icon":122},"Caching","\u002Fdocs\u002Farchitecture\u002Fcaching","docs\u002F9.architecture\u002F1.caching","i-lucide-database",{"title":124,"path":125,"stem":126,"icon":127},"Messaging and Queueing","\u002Fdocs\u002Farchitecture\u002Fmessaging-and-queueing","docs\u002F9.architecture\u002F2.messaging-and-queueing","i-lucide-message-square",{"title":129,"path":130,"stem":131,"icon":132},"GitHub Comment Rendering","\u002Fdocs\u002Farchitecture\u002Fgithub-comment-rendering","docs\u002F9.architecture\u002F3.github-comment-rendering","i-lucide-github",{"title":134,"path":135,"stem":136},"GitHub Integration","\u002Fdocs\u002Farchitecture\u002Fgithub-integration","docs\u002F9.architecture\u002F4.github-integration",{"title":138,"path":139,"stem":140},"LLM Settings and Secret Storage","\u002Fdocs\u002Farchitecture\u002Fllm-settings-and-secret-storage","docs\u002F9.architecture\u002F5.llm-settings-and-secret-storage",{"title":142,"path":143,"stem":144},"Organization Activation and Routes","\u002Fdocs\u002Farchitecture\u002Forganization-activation-and-routes","docs\u002F9.architecture\u002F6.organization-activation-and-routes",{"title":146,"path":147,"stem":148,"icon":149},"MCP Uploaded-Diff Code Reviews","\u002Fdocs\u002Farchitecture\u002Fmcp-uploaded-diff-code-reviews","docs\u002F9.architecture\u002F7.mcp-uploaded-diff-code-reviews","i-lucide-file-search",{"title":151,"path":152,"stem":153},"Repository Content Ingest","\u002Fdocs\u002Farchitecture\u002Frepository-content-ingest","docs\u002F9.architecture\u002F8.repository-content-ingest",{"title":155,"path":156,"stem":157},"Telemetry Ingest","\u002Fdocs\u002Farchitecture\u002Ftelemetry-ingest","docs\u002F9.architecture\u002F9.telemetry-ingest",{"id":159,"title":109,"body":160,"description":893,"extension":894,"links":895,"meta":896,"navigation":897,"path":110,"seo":898,"stem":111,"__hash__":899},"docs\u002Fdocs\u002F6.metrics\u002F2.metrics-pipeline.md",{"type":161,"value":162,"toc":884},"minimark",[163,176,181,201,218,222,232,661,674,709,712,716,726,733,737,775,786,790,805,808,812,833,836,840,843,870,880],[164,165,166,167,170,171,175],"p",{},"The dashboard (",[168,169,104],"a",{"href":105},") is backed by a durable capture pipeline: in-process ",[172,173,174],"code",{},"System.Diagnostics.Metrics"," instruments are observed, batched, published as a message, and written to a partitioned Postgres table with automatic retention.",[177,178,180],"h2",{"id":179},"capture-rule","Capture Rule",[164,182,183,184,187,188,191,192,200],{},"A single ",[172,185,186],{},"MeterListener"," observes the ",[172,189,190],{},"ZeeqTelemetry.Metrics"," meter. A measurement is ",[193,194,195,196,199],"strong",{},"persisted only if it carries an ",[172,197,198],{},"organization_id"," tag",". Measurements without that tag still flow to OpenTelemetry exactly as before — they are simply not stored.",[164,202,203,204,206,207,210,211,214,215,217],{},"This one rule makes the pipeline self-selecting: there is no allow-list to maintain, and the pipeline's own internal diagnostics are never persisted by its own listener (they carry no ",[172,205,198],{},"). This is the ",[193,208,209],{},"feedback-loop guard"," — prefer plain logging over self-instrumenting the pipeline; if a pipeline meter is ever needed it must be a separate ",[172,212,213],{},"Meter"," instance, never ",[172,216,190],{},".",[177,219,221],{"id":220},"instrument-taxonomy","Instrument Taxonomy",[164,223,224,227,228,231],{},[172,225,226],{},"metric_type"," ",[193,229,230],{},"is"," the instrument name, verbatim — there is no mapping layer. Add a KPI by declaring an instrument and tagging it; nothing else in the pipeline changes.",[233,234,235,267],"table",{},[236,237,238],"thead",{},[239,240,241,247,250,255,258,264],"tr",{},[242,243,244,246],"th",{},[172,245,226],{}," (instrument)",[242,248,249],{},"Kind",[242,251,252],{},[172,253,254],{},"metric_value",[242,256,257],{},"Promoted columns",[242,259,260,263],{},[172,261,262],{},"tags"," (jsonb)",[242,265,266],{},"Panel",[268,269,270,301,323,351,378,404,433,457,483,507,529,559,586,612,638],"tbody",{},[239,271,272,278,281,284,293,298],{},[273,274,275],"td",{},[172,276,277],{},"zeeq_tool_call_counter",[273,279,280],{},"Counter",[273,282,283],{},"1",[273,285,286,289,290],{},[172,287,288],{},"user_email",", ",[172,291,292],{},"tool_name",[273,294,295],{},[172,296,297],{},"user_agent",[273,299,300],{},"Tool calls",[239,302,303,308,310,312,316,320],{},[273,304,305],{},[172,306,307],{},"zeeq_user_agent_counter",[273,309,280],{},[273,311,283],{},[273,313,314],{},[172,315,288],{},[273,317,318],{},[172,319,297],{},[273,321,322],{},"Tool calls by agent",[239,324,325,330,332,334,343,348],{},[273,326,327],{},[172,328,329],{},"zeeq_document_read_counter",[273,331,280],{},[273,333,283],{},[273,335,336,289,338,289,340],{},[172,337,288],{},[172,339,292],{},[172,341,342],{},"library",[273,344,345],{},[172,346,347],{},"path",[273,349,350],{},"Knowledge reads",[239,352,353,358,360,363,371,375],{},[273,354,355],{},[172,356,357],{},"zeeq_section_read_counter",[273,359,280],{},[273,361,362],{},"1 per section",[273,364,365,289,367,289,369],{},[172,366,288],{},[172,368,292],{},[172,370,342],{},[273,372,373],{},[172,374,347],{},[273,376,377],{},"Leaderboard",[239,379,380,385,387,390,398,402],{},[273,381,382],{},[172,383,384],{},"zeeq_snippet_read_counter",[273,386,280],{},[273,388,389],{},"1 per snippet",[273,391,392,289,394,289,396],{},[172,393,288],{},[172,395,292],{},[172,397,342],{},[273,399,400],{},[172,401,347],{},[273,403,377],{},[239,405,406,411,414,417,425,430],{},[273,407,408],{},[172,409,410],{},"zeeq_review_duration_ms",[273,412,413],{},"Histogram",[273,415,416],{},"elapsed ms",[273,418,419,289,422],{},[172,420,421],{},"repository_id",[172,423,424],{},"facet",[273,426,427],{},[172,428,429],{},"tokens",[273,431,432],{},"Duration percentiles\u002Fscatter",[239,434,435,440,442,445,451,454],{},[273,436,437],{},[172,438,439],{},"zeeq_review_tokens",[273,441,413],{},[273,443,444],{},"token count",[273,446,447,289,449],{},[172,448,421],{},[172,450,424],{},[273,452,453],{},"—",[273,455,456],{},"Duration\u002Ftokens",[239,458,459,464,467,470,476,480],{},[273,460,461],{},[172,462,463],{},"zeeq_review_cost_usd",[273,465,466],{},"Histogram (schema-ready; no emitter yet)",[273,468,469],{},"USD",[273,471,472,289,474],{},[172,473,421],{},[172,475,424],{},[273,477,478],{},[172,479,429],{},[273,481,482],{},"Review cost",[239,484,485,490,492,495,499,504],{},[273,486,487],{},[172,488,489],{},"zeeq_agent_session_counter",[273,491,280],{},[273,493,494],{},"1 per newly created conversation",[273,496,497],{},[172,498,288],{},[273,500,501],{},[172,502,503],{},"harness",[273,505,506],{},"Agent telemetry",[239,508,509,514,516,519,523,527],{},[273,510,511],{},[172,512,513],{},"zeeq_agent_prompt_counter",[273,515,280],{},[273,517,518],{},"1 per non-housekeeping prompt",[273,520,521],{},[172,522,288],{},[273,524,525],{},[172,526,503],{},[273,528,506],{},[239,530,531,536,538,541,547,557],{},[273,532,533],{},[172,534,535],{},"zeeq_agent_tool_call_counter",[273,537,280],{},[273,539,540],{},"1 per non-housekeeping tool result",[273,542,543,289,545],{},[172,544,288],{},[172,546,292],{},[273,548,549,289,551,289,554],{},[172,550,503],{},[172,552,553],{},"mcp_server",[172,555,556],{},"success",[273,558,506],{},[239,560,561,566,568,570,574,584],{},[273,562,563],{},[172,564,565],{},"zeeq_agent_token_usage",[273,567,413],{},[273,569,444],{},[273,571,572],{},[172,573,288],{},[273,575,576,289,578,289,581],{},[172,577,503],{},[172,579,580],{},"model",[172,582,583],{},"token_kind",[273,585,506],{},[239,587,588,593,595,597,601,610],{},[273,589,590],{},[172,591,592],{},"zeeq_agent_cost_usd",[273,594,413],{},[273,596,469],{},[273,598,599],{},[172,600,288],{},[273,602,603,289,605,289,607],{},[172,604,503],{},[172,606,580],{},[172,608,609],{},"cost_source",[273,611,506],{},[239,613,614,619,621,624,628,636],{},[273,615,616],{},[172,617,618],{},"zeeq_agent_cost_units_raw",[273,620,413],{},[273,622,623],{},"provider-native raw units",[273,625,626],{},[172,627,288],{},[273,629,630,289,632,289,634],{},[172,631,503],{},[172,633,580],{},[172,635,609],{},[273,637,506],{},[239,639,640,645,647,650,652,659],{},[273,641,642],{},[172,643,644],{},"zeeq_agent_pr_link_counter",[273,646,280],{},[273,648,649],{},"1 per newly created PR-session link",[273,651,453],{},[273,653,654,289,656],{},[172,655,503],{},[172,657,658],{},"link_origin",[273,660,506],{},[164,662,663,664,667,668,670,671,673],{},"A metric event is a ",[193,665,666],{},"sparse wide event",": a handful of promoted columns (indexed) plus a ",[172,669,262],{}," jsonb bag for everything else. A provider or call site that does not populate a field simply leaves it null (for example, a provider that reports no token usage never emits ",[172,672,439],{},", so the row is absent rather than zero).",[164,675,676,677,679,680,683,684,686,687,689,690,289,692,289,694,289,696,289,698,289,700,702,703,705,706,708],{},"Agent telemetry emitters use the existing promoted tag names, not new aliases: ",[172,678,198],{}," is required for capture, ",[172,681,682],{},"user"," is promoted into the stored ",[172,685,288],{}," column, and ",[172,688,292],{}," is promoted into the stored tool column. Harness-specific dimensions such as ",[172,691,503],{},[172,693,580],{},[172,695,583],{},[172,697,609],{},[172,699,553],{},[172,701,556],{},", and ",[172,704,658],{}," remain in ",[172,707,262],{}," until a dashboard query needs to promote or group by them.",[164,710,711],{},"Agent session metrics are emitted only after the normalized domain transaction succeeds. The session counter uses the domain store's newly-created conversation keys, so replaying telemetry for an existing conversation does not increment it again. Prompt, tool, token, and cost metrics skip housekeeping events such as title generation and progress messages. USD costs and provider-native raw billing units are intentionally separate histograms so dashboards never mix currencies and opaque provider units.",[177,713,715],{"id":714},"flow","Flow",[717,718,724],"pre",{"className":719,"code":721,"language":722,"meta":723},[720],"language-text","Instrument.Add\u002FRecord (tagged organization_id)\n  -> MeterListener on ZeeqTelemetry.Metrics\n  -> bounded channel (capacity 10k, DropWrite when full)\n  -> batch: flush at 1,000 samples OR after 2s linger\n  -> publish MetricBatchMessage (ISystemMessage, low-priority) via IZeeqMessagePublisher\n  -> MetricBatchMessageHandler\n  -> PostgresMetricEventStore (AddRange + one SaveChangesAsync)\n  -> zeeq_metric_events\n","text","",[172,725,721],{"__ignoreMap":723},[164,727,728,729,732],{},"The channel is bounded and drops on overflow (",[172,730,731],{},"DropWrite","): metrics are best-effort and must never block or take down a request path. Publish failures are swallowed and logged for the same reason.",[177,734,736],{"id":735},"storage-and-retention","Storage and Retention",[164,738,739,742,743,746,747,750,751,754,755,758,759,762,763,766,767,770,771,774],{},[172,740,741],{},"zeeq_metric_events"," is ",[193,744,745],{},"range-partitioned"," on ",[172,748,749],{},"created_at_utc"," with a composite primary key ",[172,752,753],{},"(id, created_at_utc)",". Partitions are 7 days wide, created ahead of time by pg_partman (premake 2), and dropped automatically after ",[193,756,757],{},"30 days"," (",[172,760,761],{},"retention_keep_table = false","), driven by the existing hourly ",[172,764,765],{},"run_maintenance_proc"," cron job. Partitions are ",[193,768,769],{},"logged"," (not ",[172,772,773],{},"UNLOGGED",") because Cloud SQL failover truncates unlogged tables, which would silently empty the dashboard.",[164,776,777,778,781,782,785],{},"Indexes are ",[172,779,780],{},"(organization_id, metric_type, …, created_at_utc)"," with partial ",[172,783,784],{},"IS NOT NULL"," filters on the promoted columns, so every dashboard query is partition-pruned and index-covered.",[177,787,789],{"id":788},"read-api","Read API",[164,791,792,793,796,797,800,801,804],{},"Seven read endpoints back the panels — series, percentiles, scatter, leaderboard, review volume, review findings, and overview — plus a ",[172,794,795],{},"filter-options"," endpoint that returns the distinct users, tools, authors, and repositories present in the data (repositories include removed mappings). Every route is a single-organization, window-scoped, ",[172,798,799],{},"AsNoTracking"," query cached for 30s via ",[172,802,803],{},"HybridCache",". Organization scope comes from the cookie-validated route parameter, never a free query parameter, and window\u002Fmetric-type inputs are validated against closed allow-sets.",[164,806,807],{},"Review volume\u002Ffindings and the review histograms read the code-review tables directly. Review token counts come from an LLM usage sink that accumulates usage across all tool-calling round-trips of a single reviewer run (per-provider usage shape varies; providers that report nothing simply do not emit the token metric).",[177,809,811],{"id":810},"adding-a-metric","Adding a Metric",[813,814,815,821,830],"ol",{},[816,817,818,819,217],"li",{},"Declare an instrument (counter or histogram) on ",[172,820,190],{},[816,822,823,824,826,827,829],{},"Emit it with an ",[172,825,198],{}," tag (and any promoted columns \u002F ",[172,828,262],{}," you want).",[816,831,832],{},"That's it — capture, batching, storage, and retention all apply automatically.",[164,834,835],{},"To surface it, add a read query + endpoint (or reuse the generic series\u002Fpercentile endpoints) and a dashboard panel.",[177,837,839],{"id":838},"deploy-time-verification","Deploy-Time Verification",[164,841,842],{},"Partitioning and retention are not exercised by the container-based integration tests (the test image ships pg_partman, but retention\u002Fcron behavior is time-based). Verify against a real environment via psql:",[717,844,848],{"className":845,"code":846,"language":847,"meta":723,"style":723},"language-sql shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","SELECT retention, retention_keep_table, infinite_time_partitions\nFROM partman.part_config\nWHERE parent_table = 'zeeq.zeeq_metric_events';\n","sql",[172,849,850,858,864],{"__ignoreMap":723},[851,852,855],"span",{"class":853,"line":854},"line",1,[851,856,857],{},"SELECT retention, retention_keep_table, infinite_time_partitions\n",[851,859,861],{"class":853,"line":860},2,[851,862,863],{},"FROM partman.part_config\n",[851,865,867],{"class":853,"line":866},3,[851,868,869],{},"WHERE parent_table = 'zeeq.zeeq_metric_events';\n",[164,871,872,873,876,877,879],{},"Confirm premade child partitions exist, and that ",[172,874,875],{},"cron.job_run_details"," shows a successful ",[172,878,765],{}," tick.",[881,882,883],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":723,"searchDepth":860,"depth":860,"links":885},[886,887,888,889,890,891,892],{"id":179,"depth":860,"text":180},{"id":220,"depth":860,"text":221},{"id":714,"depth":860,"text":715},{"id":735,"depth":860,"text":736},{"id":788,"depth":860,"text":789},{"id":810,"depth":860,"text":811},{"id":838,"depth":860,"text":839},"How application metrics are captured, batched, stored, and served for the dashboard.","md",null,{},{"icon":112},{"title":109,"description":893},"jR8VxT0cQRWh2IJi7FJVaL0NTtOEajSTZPWKJ6kVTpw",[901,903],{"title":104,"path":105,"stem":106,"description":902,"icon":107,"children":-1},"The home page tabbed dashboard for tool usage, code reviews, knowledge reads, and review performance.",{"title":119,"path":120,"stem":121,"description":904,"icon":122,"children":-1},"Overview of caching systems in the architecture.",1784297365800]