Skip to content

Send the Quality grade to the cloud, and stop the cloud inventing an empty one - #5121

Merged
vivekchand merged 38 commits into
mainfrom
feat/quality-cloud-parity
Sep 1, 2026
Merged

Send the Quality grade to the cloud, and stop the cloud inventing an empty one#5121
vivekchand merged 38 commits into
mainfrom
feat/quality-cloud-parity

Conversation

@vivekchand

@vivekchand vivekchand commented Aug 23, 2026

Copy link
Copy Markdown
Owner

No-PRD: Blueprint documents an implementation already captured in the feature blueprint file; requirements are tracked in docs/blueprints/quality-cloud-parity.md.

What was on screen

Same node, same runtime, same week:

localhost:8900 app.clawmetry.com
A — "90 tasks came back clean. 29 rough ones cost you $207.35", 119 runs graded "Nothing to grade yet."

Two faults

1. The grade never rode the snapshot. Every card the hosted dashboard renders needs a slice the daemon emits. Quality never had one, so the cloud had nothing to serve — the cloud-parity gate, missed.

2. The hosted container answered anyway. It has a DuckDB file of its own. Empty, but perfectly able to answer, so query_quality_sessions returned [] and the tab reported a working machine as having produced nothing. Verified against production before writing a line:

$ curl https://app.clawmetry.com/api/quality/report-card?runtime=claude_code
{"grade":"—","graded_runs":0,"total_runs":0,"store_available":true,
 "headline":"Nothing to grade yet.", ...}

store_available: true is the tell. The handler already separated "the store said nothing" from "I could not reach the store" — it just could not know its own store was a stranger's.

The fix

  • sync.py emits quality: {window_hours, all, byRuntime, thresholds}. The composer moved out of the request handler (routes/quality.py::compose_report_card) so the daemon and the request path build the identical payload.
  • Read once, compose many. The node's sessions are queried three times total (window, prior window, 30-day calibration) and grouped in Python, so fourteen runtime cards cost three queries rather than forty-two. The bounded deep scan runs once for the node; every card reuses that assessment map. Pinned by a test that counts the store reads.
  • Quiet runtimes still get a card. A runtime with no runs this week needs one saying so in its own name, or the hosted tab falls back to the node-wide card and shows another runtime's grade under this runtime's filter.
  • Calibration carried once per slice, not inline in fourteen cards where it is byte-identical: 85 kB → 61 kB.
  • The hosted process stops reading its own store for this. With CLAWMETRY_CLOUD set it returns the honest "Quality is graded on your own machine" payload, so an older daemon with no slice produces a true statement instead of a fabricated empty week.

Verified

Against the real local store (173 sessions this week):

node-wide  grade=A  graded=132/173
claude_code  A  125 runs      cursor  —  13
codex        —    7           exo     F   2
copilot      A    5           pi      B   8

tests/test_quality_cloud_parity.py — 10 tests: the slice carries node-wide + per-runtime cards; a per-runtime card never contains another runtime's runs; a quiet runtime still gets one; calibration is hoisted; the store is read exactly 3 times whatever the runtime count; the slice never raises; the hosted path says where the grade lives; the local path still reports a genuinely empty week as empty; an unreachable store is not an empty grade; precomputed assessments give the same grade as the request path.

Existing quality suites: 67 passing.

Cloud interceptor ships alongside in clawmetry-cloud.

One to remember

The first version of the daemon slice returned {} silently: sync.py imports datetime and timezone but not timedelta, and the broad except swallowed the NameError. Same shape as the module-scope NameError class we have been bitten by before.

🤖 Generated with Claude Code

https://claude.ai/code/session_0138ySWEXGWEayXCPDqWrw21

@8090-software-factory

Copy link
Copy Markdown

⚠️ Drift Bot (ClawMetry): 4 potential drift finding(s)

1. Blueprint: Cloud Fleet Dashboard

File: clawmetry/sync.py:20109

The code implements a quality snapshot slice in the daemon (sync.py:_build_quality_snapshot) that reaches the cloud dashboard, but the Cloud Fleet Dashboard blueprint does not document this slice or the corresponding cloud interceptor component. The blueprint documents CloudSpendFlowInterceptor and CloudAttentionInterceptor but has no CloudQualityInterceptor documentation.

2. Blueprint: Cloud Fleet Dashboard

File: routes/quality.py:155

The code adds a CLAWMETRY_CLOUD environment variable guard that prevents the hosted quality endpoint from reading its own empty DuckDB store when running in cloud mode. This behavior is not documented in the Cloud Fleet Dashboard blueprint's system contracts or the quality component specifications.

3. Blueprint: Local Observability Service

File: clawmetry/sync.py:16665

The code implements _build_quality_snapshot() that emits quality grades to the cloud via the snapshot, but the Local Observability Service blueprint's Quality section (ADR-041-042, Key Contracts) documents only the GET /api/quality/report-card endpoint and does not mention the snapshot slice or the daemon's responsibility to emit it.

4. Blueprint: Local Observability Service

File: routes/quality.py:155

The compose_report_card() function is split out to be reused by both the request handler and the daemon's snapshot builder, but this refactoring and its purpose (enabling cloud-parity by emitting quality via snapshot) is not documented in the Local Observability Service blueprint's quality section.

Comment thread clawmetry/sync.py
Comment thread routes/quality.py
Comment thread routes/quality.py
@github-actions

github-actions Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Visual diff

Comparing 114a482ff867 (head) against the PR base branch.

40 of 68 comparison(s) flagged (>1% pixel diff).

View Before After Diff
desktop overview ⚠️ before after diff · 100.00%
desktop flow ⚠️ before after diff · 4.05%
desktop brain before after diff · 0.01%
desktop usage ⚠️ before after diff · 6.00%
desktop crons before after diff · 0.00%
desktop memory ⚠️ before after diff · 1.38%
desktop security ⚠️ before after diff · 1.83%
desktop subagents ⚠️ before after diff · 1.36%
desktop transcripts before after diff · 0.01%
desktop logs before after diff · 0.62%
desktop skills before after diff · 0.01%
desktop models before after diff · 0.00%
desktop approvals before after diff · 0.02%
desktop alerts before after diff · 0.40%
desktop notifications before after diff · 0.01%
desktop limits ⚠️ before after diff · 1.41%
desktop clusters ⚠️ before after diff · 1.12%
desktop history ⚠️ before after diff · 1.60%
desktop channels ⚠️ before after diff · 1.25%
desktop dives ⚠️ before after diff · 1.52%
desktop harness ⚠️ before after diff · 2.30%
desktop inventory before after diff · 0.33%
desktop nemoclaw before after diff · 0.63%
desktop policy ⚠️ before after diff · 1.49%
desktop selfevolve ⚠️ before after diff · 1.65%
desktop swimlane ⚠️ before after diff · 1.43%
desktop tool-catalog before after diff · 0.01%
desktop tracing ⚠️ before after diff · 2.20%
desktop turn-anatomy before after diff · 0.41%
desktop version-impact before after diff · 0.70%
desktop context-economics before after diff · 0.01%
desktop agents ⚠️ before after diff · 1.87%
desktop evals ⚠️ before after diff · 16.77%
desktop bench before after diff · 0.16%
mobile overview ⚠️ before after diff · 100.00%
mobile flow ⚠️ before after diff · 5.32%
mobile brain ⚠️ before after diff · 6.38%
mobile usage ⚠️ before after diff · 4.16%
mobile crons before after diff · 0.01%
mobile memory ⚠️ before after diff · 1.58%
mobile security before after diff · 0.69%
mobile subagents ⚠️ before after diff · 100.00%
mobile transcripts before after diff · 0.01%
mobile logs ⚠️ before after diff · 100.00%
mobile skills ⚠️ before after diff · 1.58%
mobile models before after diff · 0.00%
mobile approvals ⚠️ before after diff · 100.00%
mobile alerts ⚠️ before after diff · 3.36%
mobile notifications ⚠️ before after diff · 100.00%
mobile limits ⚠️ before after diff · 100.00%
mobile clusters before after diff · 0.01%
mobile history ⚠️ before after diff · 100.00%
mobile channels ⚠️ before after diff · 1.55%
mobile dives before after diff · 0.06%
mobile harness before after diff · 0.64%
mobile inventory ⚠️ before after diff · 100.00%
mobile nemoclaw before after diff · 0.01%
mobile policy ⚠️ before after diff · 100.00%
mobile selfevolve before after diff · 0.73%
mobile swimlane ⚠️ before after diff · 100.00%
mobile tool-catalog ⚠️ before after diff · 100.00%
mobile tracing before after diff · 0.01%
mobile turn-anatomy before after diff · 0.00%
mobile version-impact ⚠️ before after diff · 100.00%
mobile context-economics ⚠️ before after diff · 100.00%
mobile agents ⚠️ before after diff · 100.00%
mobile evals before after diff · 0.67%
mobile bench ⚠️ before after diff · 100.00%

Folder: 114a482ff867. Full PNGs also attached as a workflow artefact.

Generated by visual-diff bot. Pixel diffs >1% flagged; eyeball the table before merging. This check is non-blocking — fail = bot bug, not a code problem.

Copy link
Copy Markdown
Owner Author

Autonomous maintainer pass (2026-08-23): all 37 CI checks green. One blocker: drift-bot is red (4 findings). Per FLYWHEEL.md §1f (just merged in #5122), this cannot be cleared after merge — it must be green before merging.

What drift-bot flagged (both require edit_blueprint via the software-factory MCP server):

  1. Cloud Fleet Dashboard blueprint — add CloudQualityInterceptor (mirrors CloudSpendFlowInterceptor / CloudAttentionInterceptor already documented there).
  2. Cloud Fleet Dashboard blueprint — document the CLAWMETRY_CLOUD guard behavior (when set, quality endpoint defers to the daemon snapshot rather than reading its own empty DuckDB).
  3. Local Observability Service blueprint, Quality section (ADR-041-042) — document that sync.py emits a quality snapshot slice via _build_quality_snapshot().
  4. Local Observability Service blueprint, Quality section — document the compose_report_card() refactor (moved from request handler so daemon and HTTP path share identical payload construction).

Path to green:

  1. read_blueprint for "Cloud Fleet Dashboard" (ID 3af0be35-7c88-4376-a74e-ea2cb1ca834c) and "Local Observability Service" (ID b6347b91-09ce-41fd-8aa1-f20066d82f5d)
  2. Decide whether the code or the Blueprint is wrong (the code is correct here — blueprints are behind the implementation)
  3. edit_blueprint to update both, matching shall-form contracts + ADR style
  4. Confirm drift-bot status turns green before merging

Downstream: cloud #2090 is also blocked until this merges and ships — see cloud #2090 for details.


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

✨ auto-fixed: merged main into branch to bring it current (was behind by several commits)


Generated by Claude Code

@8090-software-factory

Copy link
Copy Markdown

⚠️ Drift Bot (ClawMetry): 4 potential drift finding(s)

1. Blueprint: Cloud Fleet Dashboard

File: clawmetry/sync.py:20111

The code emits a quality snapshot slice in the daemon that reaches the cloud dashboard (sync.py:_build_quality_snapshot), but the Cloud Fleet Dashboard blueprint does not document a CloudQualityInterceptor component to handle this slice on the cloud side, unlike the documented CloudSpendFlowInterceptor and CloudAttentionInterceptor.

2. Blueprint: Cloud Fleet Dashboard

File: routes/quality.py:215

The code adds a CLAWMETRY_CLOUD environment variable guard that prevents the hosted quality endpoint from reading its own empty DuckDB store when running in cloud mode, but this behavior and its purpose (ensuring cloud-parity by refusing to answer from an unavailable store) is not documented in the Cloud Fleet Dashboard blueprint.

3. Blueprint: Local Observability Service

File: clawmetry/sync.py:16665

The code implements _build_quality_snapshot() that emits quality grades from the daemon to the cloud via the encrypted snapshot, but the Local Observability Service blueprint's Quality section (ADR-041-042) documents only the GET /api/quality/report-card endpoint and does not mention the daemon's responsibility to emit quality snapshot slices.

4. Blueprint: Local Observability Service

File: routes/quality.py:95

The code refactors compose_report_card() to be split out from the request handler and reused by the daemon's snapshot builder, enabling cloud-parity by emitting identical quality payloads from both paths. This architectural change and its purpose is not documented in the Local Observability Service blueprint's quality section.

Comment thread clawmetry/sync.py
Comment thread routes/quality.py
Comment thread clawmetry/sync.py
github-actions Bot pushed a commit that referenced this pull request Aug 23, 2026
@8090-software-factory

Copy link
Copy Markdown

⚠️ Drift Bot (ClawMetry): 4 potential drift finding(s)

1. Blueprint: Cloud Fleet Dashboard

File: clawmetry/sync.py:16665

The code implements _build_quality_snapshot() in the daemon that emits a quality report card slice to the cloud snapshot, but the Cloud Fleet Dashboard blueprint does not document a CloudQualityInterceptor component to handle this slice on the cloud side, unlike the documented CloudSpendFlowInterceptor and CloudAttentionInterceptor.

2. Blueprint: Cloud Fleet Dashboard

File: routes/quality.py:203

The code adds a CLAWMETRY_CLOUD environment variable guard that prevents the hosted quality endpoint from reading its own empty DuckDB store when running in cloud mode, returning an honest unavailability message instead, but this behavior and its architectural purpose (ensuring cloud-parity) is not documented in the Cloud Fleet Dashboard blueprint.

3. Blueprint: Local Observability Service

File: clawmetry/sync.py:16665

The code implements _build_quality_snapshot() that emits quality grades from the daemon to the cloud via the encrypted snapshot slice, but the Local Observability Service blueprint's Quality section (ADR-041-042) documents only the GET /api/quality/report-card endpoint and does not mention the daemon's responsibility to emit quality snapshot slices.

4. Blueprint: Local Observability Service

File: routes/quality.py:95

The code refactors compose_report_card() to be split out from the request handler and reused by the daemon's snapshot builder, enabling cloud-parity by emitting identical quality payloads from both paths, but this architectural change and its purpose is not documented in the Local Observability Service blueprint's quality section.

Comment thread clawmetry/sync.py
Comment thread routes/quality.py
github-actions Bot pushed a commit that referenced this pull request Aug 23, 2026

Copy link
Copy Markdown
Owner Author

PR mergeability janitor (automated sweep)

This PR is BLOCKED by a real CI failure — not a transient issue, not rerunnable:

  • Check: drift-bot (gates "E2E Gate (required)")
  • Finding: Drift Bot found 4 drift finding(s) on commit 063216a8b971
  • Status set at: 2026-08-23T12:39:40Z

The Drift Bot caught a semantic contradiction between this diff and a tracked Blueprint. This requires human review and resolution — the janitor does not resolve drift findings automatically.

Note: this branch is also behind main (base was 818cbdeb, current main is 85ed2922). Once the drift findings are resolved, a rebase onto current main will also be needed before merge.


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

✨ auto-fixed: branch was BEHIND main (base was 818cbde, main advanced to 85ed292 via 5 PRs); merged main into branch so CI reruns on current base.


Generated by Claude Code

@8090-software-factory

Copy link
Copy Markdown

⚠️ Drift Bot (ClawMetry): 4 potential drift finding(s)

1. Blueprint: Cloud Fleet Dashboard

File: clawmetry/sync.py:16665

The code implements _build_quality_snapshot() that emits a quality report card slice to the cloud snapshot, but the Cloud Fleet Dashboard blueprint does not document a CloudQualityInterceptor component to handle this slice on the cloud side, unlike the documented CloudSpendFlowInterceptor and CloudAttentionInterceptor.

2. Blueprint: Cloud Fleet Dashboard

File: routes/quality.py:203

The code adds a CLAWMETRY_CLOUD environment variable guard that prevents the hosted quality endpoint from reading its own empty DuckDB store when in cloud mode, returning an honest unavailability message instead. This behavior and its architectural purpose (ensuring cloud-parity) are not documented in the Cloud Fleet Dashboard blueprint.

3. Blueprint: Local Observability Service

File: clawmetry/sync.py:16665

The code implements _build_quality_snapshot() that emits quality grades from the daemon to the cloud via the encrypted snapshot slice, but the Local Observability Service blueprint's Quality section (ADR-041-042) documents only the GET /api/quality/report-card endpoint and does not mention the daemon's responsibility to emit quality snapshot slices.

4. Blueprint: Local Observability Service

File: routes/quality.py:95

The code refactors compose_report_card() to be split out from the request handler and reused by the daemon's snapshot builder, enabling cloud-parity by emitting identical quality payloads from both paths. This architectural change and its purpose are not documented in the Local Observability Service blueprint's quality section.

Comment thread clawmetry/sync.py
Comment thread routes/quality.py

Copy link
Copy Markdown
Owner Author

blocked on author decision — skipping (auto-mergeability sweep): the drift-bot required commit status is failing (4 findings: CloudQualityInterceptor and CLAWMETRY_CLOUD guard undocumented in Cloud Fleet Dashboard blueprint; compose_report_card() refactoring undocumented in Local Observability Service blueprint). Fix requires updating the two blueprints via edit_blueprint at factory.8090.ai — outside GitHub and not a code change.


Generated by Claude Code

github-actions Bot pushed a commit that referenced this pull request Aug 23, 2026

Copy link
Copy Markdown
Owner Author

Autonomous maintainer check-in (2026-08-23)

All CI checks pass except one: the E2E Gate fails because Drift Bot returned failure. The E2E Gate log at T+62s shows:

Drift Bot: failed: 1 of 1 matching check(s) failed
    'drift-bot': failure
FAIL: required checks did not pass: - Drift Bot

Every other required check (OSS golden path, MOAT Keystone, E2E Browser Tests, Syntax & Lint, API Tests x3 OS, MOAT Verifier, Entitlement API tests, pip install x4, Wheel install, Store invariants) passed green.

Drift Bot checks whether the diff contradicts a Blueprint in the 8090 Software Factory spec database. The check runs externally and its output is not available in this context, so the specific blueprint conflict cannot be diagnosed here.

Human action needed: review the Drift Bot output linked in the check run, identify which Blueprint assertion the quality-parity change conflicts with, and either (a) update the implementation to satisfy the Blueprint, or (b) update the Blueprint in the spec database to reflect the new behavior, then re-run Drift Bot.

The cloud-side counterpart (#clawmetry-cloud/2090) is blocked on this PR merging first (it reads quality from the snapshot, which only ships once this PR is in a released version and the Dockerfile pin is bumped).


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

✨ auto-fixed: merged main into branch (was behind; branch updated to current main HEAD)


Generated by Claude Code

@8090-software-factory

Copy link
Copy Markdown

⚠️ Drift Bot (ClawMetry): 4 potential drift finding(s)

1. Blueprint: Local Observability Service

File: clawmetry/sync.py:16741

The code implements _build_quality_snapshot() that emits quality report cards to the cloud snapshot, but the Local Observability Service blueprint's Quality section (ADR-041/042) documents only the GET /api/quality/report-card endpoint and does not mention the daemon's responsibility to emit quality snapshot slices for cloud-parity.

2. Blueprint: Cloud Fleet Dashboard

File: clawmetry/sync.py:20187

The code emits a quality snapshot slice from the daemon that reaches the cloud dashboard, but the Cloud Fleet Dashboard blueprint documents CloudSpendFlowInterceptor and CloudAttentionInterceptor but does not document a CloudQualityInterceptor component to handle this slice on the cloud side.

3. Blueprint: Cloud Fleet Dashboard

File: routes/quality.py:203

The code adds a CLAWMETRY_CLOUD environment variable guard that prevents the hosted quality endpoint from reading its own empty DuckDB store when in cloud mode, returning an honest unavailability message instead. This cloud-parity behavior and its architectural purpose are not documented in the Cloud Fleet Dashboard blueprint.

4. Blueprint: Local Observability Service

File: routes/quality.py:95

The code refactors compose_report_card() to be split out from the request handler and reused by the daemon's snapshot builder, enabling cloud-parity by emitting identical quality payloads from both paths. This architectural change and its purpose are not documented in the Local Observability Service blueprint's quality section.

Comment thread clawmetry/sync.py
Comment thread clawmetry/sync.py
Comment thread routes/quality.py
github-actions Bot pushed a commit that referenced this pull request Aug 23, 2026

Copy link
Copy Markdown
Owner Author

✨ auto-fixed: branch was behind main (base SHA 979fc06439c71c); updated via update_pull_request_branch to merge latest main into the branch.


Generated by Claude Code

@8090-software-factory

Copy link
Copy Markdown

⚠️ Drift Bot (ClawMetry): 8 potential drift finding(s)

1. Blueprint: Local Observability Service

File: clawmetry/sync.py:17680

The sync daemon implements _build_quality_snapshot() to emit node-wide and per-runtime quality report cards as an encrypted snapshot slice for cloud parity, but this responsibility and the "read once, compose many" optimization pattern are not documented in the Local Observability Service blueprint.

2. Blueprint: Cloud Fleet Dashboard

File: clawmetry/sync.py:21567

The sync daemon adds a quality snapshot slice to sync_system_snapshot() for the cloud dashboard, but the Cloud Fleet Dashboard blueprint does not document a CloudQualityInterceptor component for consuming the quality slice alongside the existing CloudSpendFlowInterceptor and CloudAttentionInterceptor.

3. Blueprint: Local Observability Service

File: routes/quality.py:95

The code refactors compose_report_card() as a standalone importable function that both the daemon's snapshot builder and the request handler reuse to build identical payloads, enabling "read once, compose many" without per-runtime queries, but this architectural pattern is not documented in the Local Observability Service blueprint.

4. Blueprint: Local Observability Service

File: routes/quality.py:169

The code implements unavailable_report_card() to maintain a distinction between unreachable store (None) and empty store ([]), returning honest "Quality is graded on your own machine" messages for cloud-parity, but this contract and the two failure modes are not documented in the Local Observability Service blueprint.

5. Blueprint: Cloud Fleet Dashboard

File: routes/quality.py:220

The code adds a CLAWMETRY_CLOUD environment variable guard that prevents the hosted quality endpoint from reading its own empty DuckDB store, returning an honest unavailability message instead, but this cloud-parity behavior and its architectural purpose are not documented in the Cloud Fleet Dashboard blueprint.

6. Blueprint: Local Observability Service

File: clawmetry/sync.py:17719

The daemon's _build_quality_snapshot() implements a bounded-read strategy where sessions are queried exactly three times total (current window, prior window, 30-day calibration) and grouped in Python rather than per-runtime, but this query optimization pattern and its load-bearing contract are not documented in the Local Observability Service blueprint.

7. Blueprint: Local Observability Service

File: clawmetry/sync.py:17750

The daemon's _build_quality_snapshot() implements a quiet-runtime rule where every runtime seen in either the current window or 30-day history gets a per-runtime card in byRuntime even if quiet this week, but this contract preventing hosted tab fallback to node-wide cards is not documented in the Local Observability Service blueprint.

8. Blueprint: Local Observability Service

File: clawmetry/sync.py:17760

The daemon's _build_quality_snapshot() hoists calibration thresholds to the slice root and removes them from each per-runtime card to reduce payload size by ~25% (85 kB → 61 kB), but this payload optimization pattern and the per-slice vs per-card contract for thresholds distribution are not documented in the Local Observability Service blueprint.

Comment thread clawmetry/sync.py
}


_QUALITY_SNAPSHOT_WINDOW_HOURS = 168 # 7d — what the Quality tab asks for

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Drift Bot (ClawMetry) — Blueprint: Local Observability Service

The sync daemon implements _build_quality_snapshot() to emit node-wide and per-runtime quality report cards as an encrypted snapshot slice for cloud parity, but this responsibility and the "read once, compose many" optimization pattern are not documented in the Local Observability Service blueprint.

Comment thread clawmetry/sync.py
"governance": _build_governance(),
"dailyUsage": _du, # #2142: computed once above, shared with `spending`
"reliability": _build_reliability(),
"quality": _build_quality_snapshot(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Drift Bot (ClawMetry) — Blueprint: Cloud Fleet Dashboard

The sync daemon adds a quality snapshot slice to sync_system_snapshot() for the cloud dashboard, but the Cloud Fleet Dashboard blueprint does not document a CloudQualityInterceptor component for consuming the quality slice alongside the existing CloudSpendFlowInterceptor and CloudAttentionInterceptor.

Comment thread routes/quality.py
``?window=7d`` (default), ``?runtime=<id>`` (optional scope). No auth gate
— this is the free-tier home for the "is my agent OK?" answer, same
rationale as /api/evaluators and /api/evals/metrics.
def compose_report_card(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Drift Bot (ClawMetry) — Blueprint: Local Observability Service

The code refactors compose_report_card() as a standalone importable function that both the daemon's snapshot builder and the request handler reuse to build identical payloads, enabling "read once, compose many" without per-runtime queries, but this architectural pattern is not documented in the Local Observability Service blueprint.

Copy link
Copy Markdown
Owner Author

Automated sweep — blocker diagnosed, cannot self-resolve

The E2E Gate required check is failing due to Drift Bot (8090 Software Factory) posting a drift-bot: failure commit status. This is an external review system that evaluates the product record; it cannot be unblocked by pushing code.

What was confirmed:

  • All other CI sub-checks pass (lint, API tests, OSS golden path, MOAT, etc.)
  • drift-bot commit status = failure (actively posted, not merely absent)

What's needed to unblock:

  • The product record linked in this PR needs to be accepted by 8090 Software Factory, or a No-PRD: <reason> declaration needs to satisfy Drift Bot's review criteria.

No code changes were pushed during this sweep. The PR is otherwise ready for merge once the Drift Bot status clears.


Generated by Claude Code

github-actions Bot pushed a commit that referenced this pull request Sep 1, 2026

Copy link
Copy Markdown
Owner Author

blocked on author decision — skipping (auto-mergeability sweep)

Drift Bot is posting a failure on the drift-bot commit status (8090 Software Factory). Fixing requires updating the relevant Blueprint in the external 8090 Software Factory app — not resolvable from within this repository.


Generated by Claude Code

@8090-software-factory

Copy link
Copy Markdown

⚠️ Drift Bot (ClawMetry): 8 potential drift finding(s)

1. Blueprint: Local Observability Service

File: clawmetry/sync.py:17685

The sync daemon implements _build_quality_snapshot() to emit node-wide and per-runtime quality report cards as an encrypted snapshot slice for cloud parity, but this new responsibility and the "read once, compose many" optimization pattern are not documented in the Local Observability Service blueprint.

2. Blueprint: Cloud Fleet Dashboard

File: clawmetry/sync.py:21635

The sync daemon adds a quality snapshot slice to sync_system_snapshot() for the cloud dashboard, but the Cloud Fleet Dashboard blueprint does not document a CloudQualityInterceptor component for consuming the quality slice alongside the existing CloudSpendFlowInterceptor and CloudAttentionInterceptor.

3. Blueprint: Local Observability Service

File: routes/quality.py:95

The code refactors compose_report_card() as a standalone importable function that both the daemon's snapshot builder and the request handler reuse to build identical payloads, enabling "read once, compose many" without per-runtime queries, but this architectural pattern is not documented in the Local Observability Service blueprint.

4. Blueprint: Local Observability Service

File: routes/quality.py:169

The code implements unavailable_report_card() to maintain a distinction between unreachable store (None) and empty store ([]), returning honest "Quality is graded on your own machine" messages for cloud-parity, but this contract and the two failure modes are not documented in the Local Observability Service blueprint.

5. Blueprint: Cloud Fleet Dashboard

File: routes/quality.py:207

The code adds a CLAWMETRY_CLOUD environment variable guard that prevents the hosted quality endpoint from reading its own empty DuckDB store, returning an honest unavailability message instead, but this cloud-parity behavior and its architectural purpose are not documented in the Cloud Fleet Dashboard blueprint.

6. Blueprint: Local Observability Service

File: clawmetry/sync.py:17719

The daemon's _build_quality_snapshot() implements a bounded-read strategy where sessions are queried exactly three times total (current window, prior window, 30-day calibration) and grouped in Python rather than per-runtime, but this query optimization pattern and its load-bearing contract are not documented in the Local Observability Service blueprint.

7. Blueprint: Local Observability Service

File: clawmetry/sync.py:17750

The daemon's _build_quality_snapshot() implements a quiet-runtime rule where every runtime seen in either the current window or 30-day history gets a per-runtime card in byRuntime even if quiet this week, but this contract preventing hosted tab fallback to node-wide cards is not documented in the Local Observability Service blueprint.

8. Blueprint: Local Observability Service

File: clawmetry/sync.py:17760

The daemon's _build_quality_snapshot() hoists calibration thresholds to the slice root and removes them from each per-runtime card to reduce payload size by ~25% (85 kB → 61 kB), but this payload optimization pattern and the per-slice vs per-card contract for thresholds distribution are not documented in the Local Observability Service blueprint.

Comment thread clawmetry/sync.py
}


_QUALITY_SNAPSHOT_WINDOW_HOURS = 168 # 7d — what the Quality tab asks for

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Drift Bot (ClawMetry) — Blueprint: Local Observability Service

The sync daemon implements _build_quality_snapshot() to emit node-wide and per-runtime quality report cards as an encrypted snapshot slice for cloud parity, but this new responsibility and the "read once, compose many" optimization pattern are not documented in the Local Observability Service blueprint.

Comment thread clawmetry/sync.py
"governance": _build_governance(),
"dailyUsage": _du, # #2142: computed once above, shared with `spending`
"reliability": _build_reliability(),
"quality": _build_quality_snapshot(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Drift Bot (ClawMetry) — Blueprint: Cloud Fleet Dashboard

The sync daemon adds a quality snapshot slice to sync_system_snapshot() for the cloud dashboard, but the Cloud Fleet Dashboard blueprint does not document a CloudQualityInterceptor component for consuming the quality slice alongside the existing CloudSpendFlowInterceptor and CloudAttentionInterceptor.

…y Service v26, Cloud Fleet Dashboard v15)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011JYHXKUSfu72qPh2zuq92N
@8090-software-factory

Copy link
Copy Markdown

⚠️ Drift Bot (ClawMetry): 8 potential drift finding(s)

1. Blueprint: Local Observability Service

File: clawmetry/sync.py:17687

The sync daemon implements _build_quality_snapshot() to emit node-wide and per-runtime quality report cards as an encrypted snapshot slice for cloud parity, but this new responsibility and the "read once, compose many" optimization pattern are not documented in the blueprint.

2. Blueprint: Cloud Fleet Dashboard

File: clawmetry/sync.py:21635

The sync daemon adds a quality snapshot slice to sync_system_snapshot() for the cloud dashboard, but the Cloud Fleet Dashboard blueprint does not document a CloudQualityInterceptor component for consuming the quality slice alongside the existing CloudSpendFlowInterceptor and CloudAttentionInterceptor.

3. Blueprint: Local Observability Service

File: routes/quality.py:95

The code refactors compose_report_card() as a standalone importable function that both the daemon's snapshot builder and the request handler reuse to build identical payloads, enabling "read once, compose many" without per-runtime queries, but this architectural pattern is not documented in the Local Observability Service blueprint.

4. Blueprint: Local Observability Service

File: routes/quality.py:169

The code implements unavailable_report_card() to maintain a distinction between unreachable store (None) and empty store ([]), returning honest "Quality is graded on your own machine" messages for cloud-parity, but this contract and the two failure modes are not documented in the Local Observability Service blueprint.

5. Blueprint: Cloud Fleet Dashboard

File: routes/quality.py:207

The code adds a CLAWMETRY_CLOUD environment variable guard that prevents the hosted quality endpoint from reading its own empty DuckDB store, returning an honest unavailability message instead, but this cloud-parity behavior and its architectural purpose are not documented in the Cloud Fleet Dashboard blueprint.

6. Blueprint: Local Observability Service

File: clawmetry/sync.py:17719

The daemon's _build_quality_snapshot() implements a bounded-read strategy where sessions are queried exactly three times total (current window, prior window, 30-day calibration) and grouped in Python rather than per-runtime, but this query optimization pattern and its load-bearing contract are not documented in the Local Observability Service blueprint.

7. Blueprint: Local Observability Service

File: clawmetry/sync.py:17750

The daemon's _build_quality_snapshot() implements a quiet-runtime rule where every runtime seen in either the current window or 30-day history gets a per-runtime card in byRuntime even if quiet this week, but this contract preventing hosted tab fallback to node-wide cards is not documented in the Local Observability Service blueprint.

8. Blueprint: Local Observability Service

File: clawmetry/sync.py:17760

The daemon's _build_quality_snapshot() hoists calibration thresholds to the slice root and removes them from each per-runtime card to reduce payload size by ~25% (85 kB → 61 kB), but this payload optimization pattern and the per-slice vs per-card contract for thresholds distribution are not documented in the Local Observability Service blueprint.

Comment thread clawmetry/sync.py

_QUALITY_SNAPSHOT_WINDOW_HOURS = 168 # 7d — what the Quality tab asks for


Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Drift Bot (ClawMetry) — Blueprint: Local Observability Service

The sync daemon implements _build_quality_snapshot() to emit node-wide and per-runtime quality report cards as an encrypted snapshot slice for cloud parity, but this new responsibility and the "read once, compose many" optimization pattern are not documented in the blueprint.

Comment thread clawmetry/sync.py
"governance": _build_governance(),
"dailyUsage": _du, # #2142: computed once above, shared with `spending`
"reliability": _build_reliability(),
"quality": _build_quality_snapshot(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Drift Bot (ClawMetry) — Blueprint: Cloud Fleet Dashboard

The sync daemon adds a quality snapshot slice to sync_system_snapshot() for the cloud dashboard, but the Cloud Fleet Dashboard blueprint does not document a CloudQualityInterceptor component for consuming the quality slice alongside the existing CloudSpendFlowInterceptor and CloudAttentionInterceptor.

…ndex refresh)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011JYHXKUSfu72qPh2zuq92N
@8090-software-factory

Copy link
Copy Markdown

⚠️ Drift Bot (ClawMetry): 8 potential drift finding(s)

1. Blueprint: Local Observability Service

File: clawmetry/sync.py:17685

The sync daemon now implements a QualitySnapshotBuilder (_build_quality_snapshot) to emit quality report cards in the encrypted snapshot for cloud parity, but the Local Observability Service blueprint does not document this new component responsibility or its behavior.

2. Blueprint: Local Observability Service

File: routes/quality.py:95

The code extracts compose_report_card() as a standalone importable function enabling "read once, compose many" optimization, but this architectural pattern is not documented in the Local Observability Service blueprint.

3. Blueprint: Local Observability Service

File: routes/quality.py:169

The code implements unavailable_report_card() to distinguish between unreachable store (None) and empty store ([]), returning honest "Quality is graded on your own machine" messages, but this distinction between failure modes is not documented in the Local Observability Service blueprint.

4. Blueprint: Cloud Fleet Dashboard

File: routes/quality.py:207

The quality endpoint uses a CLAWMETRY_CLOUD environment variable guard to prevent reading the hosted container's empty DuckDB store, returning honest unavailability messages instead for cloud parity. This cloud-parity behavior is not documented in the Cloud Fleet Dashboard blueprint.

5. Blueprint: Local Observability Service

File: clawmetry/sync.py:17715

The sync daemon implements a bounded-read strategy where quality sessions are queried exactly three times total (current window, prior window, 30-day calibration) and grouped in Python rather than per-runtime, but this optimization contract is not documented in the Local Observability Service blueprint.

6. Blueprint: Local Observability Service

File: clawmetry/sync.py:17750

The sync daemon implements a quiet-runtime rule where every runtime seen in the 30-day history gets a per-runtime card in byRuntime even if quiet this week, preventing hosted tab fallback to node-wide cards. This contract is not documented in the Local Observability Service blueprint.

7. Blueprint: Local Observability Service

File: clawmetry/sync.py:17760

The sync daemon hoists calibration thresholds to the slice root rather than embedding them in each per-runtime card, reducing payload size by ~25%. This payload optimization pattern is not documented in the Local Observability Service blueprint.

8. Blueprint: Cloud Fleet Dashboard

File: clawmetry/sync.py:21632

The sync daemon adds a quality snapshot slice to sync_system_snapshot() for cloud parity. While the Cloud Fleet Dashboard blueprint documents a CloudQualityInterceptor component, it does not document how it consumes the quality slice or reattaches calibration from the slice root.

Comment thread clawmetry/sync.py
}


_QUALITY_SNAPSHOT_WINDOW_HOURS = 168 # 7d — what the Quality tab asks for

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Drift Bot (ClawMetry) — Blueprint: Local Observability Service

The sync daemon now implements a QualitySnapshotBuilder (_build_quality_snapshot) to emit quality report cards in the encrypted snapshot for cloud parity, but the Local Observability Service blueprint does not document this new component responsibility or its behavior.

Comment thread routes/quality.py
``?window=7d`` (default), ``?runtime=<id>`` (optional scope). No auth gate
— this is the free-tier home for the "is my agent OK?" answer, same
rationale as /api/evaluators and /api/evals/metrics.
def compose_report_card(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Drift Bot (ClawMetry) — Blueprint: Local Observability Service

The code extracts compose_report_card() as a standalone importable function enabling "read once, compose many" optimization, but this architectural pattern is not documented in the Local Observability Service blueprint.

Comment thread routes/quality.py
# The hosted dashboard has no run history of its own — it ships with an
# EMPTY DuckDB, which answers queries rather than failing them. Reading it
# here produced "Nothing to grade yet" for machines that were grading
# fine, so the hosted process refuses to answer from it at all. The real

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Drift Bot (ClawMetry) — Blueprint: Cloud Fleet Dashboard

The quality endpoint uses a CLAWMETRY_CLOUD environment variable guard to prevent reading the hosted container's empty DuckDB store, returning honest unavailability messages instead for cloud parity. This cloud-parity behavior is not documented in the Cloud Fleet Dashboard blueprint.

… pinned)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011JYHXKUSfu72qPh2zuq92N
@8090-software-factory

Copy link
Copy Markdown

✅ Drift Bot (ClawMetry): no drift detected

Drift Bot analyzed the changed files against this project's blueprints and requirements and found no drift.

github-actions Bot pushed a commit that referenced this pull request Sep 1, 2026
@vivekchand
vivekchand merged commit 2abca27 into main Sep 1, 2026
45 checks passed
@vivekchand
vivekchand deleted the feat/quality-cloud-parity branch September 1, 2026 22:45
vivekchand added a commit that referenced this pull request Sep 1, 2026
… shipped in the release cut from #5427)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011JYHXKUSfu72qPh2zuq92N
vivekchand added a commit that referenced this pull request Sep 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants