[oncall-telemetry] Default report window to rolling 7 days ending today, Fixes AB#3683194#447
[oncall-telemetry] Default report window to rolling 7 days ending today, Fixes AB#3683194#447shahzaibj wants to merge 5 commits into
Conversation
…3683194
Fadi's ★4 skill-effectiveness feedback (Jun 2026): "The telemetry skill was
certainly helpful, the biggest feedback is that it seemed to capture the wrong
timeframe (didn't capture the most recent 6 days)."
Root cause (repro'd on today's clock, Thu 2026-07-09):
The old bootstrap-report.ps1 computed "reporting Sunday" as the most recent
Sunday strictly before today — i.e. the Sunday of the CURRENTLY IN-PROGRESS
week. Run on a Thursday, it picked Sun 2026-07-05 -> Sat 2026-07-11 where
Saturday is 2 days in the future, so the WoW section queried a 4-day partial
window and dropped the last complete week. Exactly Fadi's "missed the last 6
days" complaint. SKILL.md compounded this by asking the model to confirm the
Sunday with the user — a manual coax that the developer shouldn't have to do.
Fix (deep — user picked "rewrite to rolling [today-7d, today) everywhere except
60-day trend" over the smaller Sun-Sat-preserving option):
* bootstrap-report.ps1: replaced -ReportingSunday with -EndDate (default: today
UTC). Computes curStart = curEnd-7d, prevStart = curEnd-14d, and 60d trend
window = 8 complete Sun-Sat weeks ending startofweek(curEnd). Stamps the
resolved window into the report's <title>, <div class="meta">, and Generated
banner so header dates can never drift from what was queried. Refuses future
end-dates. Collision fingerprint stopped keying off title/meta (which bootstrap
now rewrites unconditionally) — uses firstKpi + size ratio only.
* 15 KQL templates rewritten:
- 12 primary/WoW queries now use half-open [prevStart, curEnd) with
wk = iff(EventInfo_Time >= curStart, curStart, prevStart) → two rows per
key, downstream JS helpers unchanged.
- 3 60-day-trend queries keep startofweek() bucketing (weekly denominators
still matter for the long-horizon view); only <END> placeholder renamed to
<TREND_END> and its semantics clarified as startofweek(today) exclusive.
- Placeholder audit is now consistent across all 15 files
(<CUR_END>/<CUR_START>/<PREV_START>/<TREND_START>/<TREND_END>).
* JS helpers (agg.js, bucket-trends.js, summarize-attribution.js): schema
detection continues to work — wk sorts lexicographically so smallest = prev,
largest = cur regardless of whether it's a Sunday label or a rolling-window
boundary. Docstrings updated.
* report-template.html: <title>/meta stamped by bootstrap; header comment
updated to describe stamping. template-readme.md § Date fields rewritten:
bootstrap owns every date field; author never edits them.
* SKILL.md: rewrote "Inputs to confirm §1" — do NOT ask the user for a
reporting date by default. Just run bootstrap; it stamps the window
automatically. Override via -EndDate only when user explicitly requests a
non-default window. Filename convention <sunday> → <end-date> throughout.
All KQL placeholder examples switched to the rolling-window form.
* kusto-cheatsheet.md: added § 3 "Rolling 7-day WoW window" with canonical
template. Kept § 7 startofweek()-alignment note but scoped it to 60-day trend.
* validate-report.ps1: new check #11 asserts meta-line "Last 7 days" dates are
self-consistent with the filename's end-date (catches any hand-edit that
broke the auto-stamp, or a stale template stub being published fresh).
BREAKING (called out intentionally):
* bootstrap-report.ps1: -ReportingSunday parameter removed; use -EndDate.
The old name encoded the exact semantic mismatch that caused the bug.
* Filename: oncall-wow-report-<end-date>.html (was <sunday>.html).
Verification:
Run on 2026-07-09 → correctly resolves to [2026-07-02, 2026-07-09).
-EndDate 2026-07-02 → resolves to [2026-06-25, 2026-07-02).
-EndDate 2027-01-01 → refused (future date).
Same-day re-bootstrap of unfilled stub → silently overwrites.
Same-day re-bootstrap after author populated KPI → HARD HALT exit 2 unless
-Force. Validator check #11 passes on fresh stub, FAILs on hand-mutated
meta line.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
✅ Work item link check complete. Description contains link AB#3683194 to an Azure Boards work item. |
1 similar comment
|
✅ Work item link check complete. Description contains link AB#3683194 to an Azure Boards work item. |
|
❌ Invalid work item number: AB#3683194 ##. Work item number must be a valid integer. Click here to learn more. |
…today Follow-up to AB#3683194 (Fadi's feedback): the 60-day trend section ended on the last complete Sunday (startofweek(today)), lagging 3-6 days behind "today". Move it to the literal last 60 days [curEnd-60d, curEnd) so the chart ends today with the current in-progress week as its final (partial) bar. To keep regression/improvement classification honest, split display from classification: bucket-trends.js gains --include-partial-end, which charts the partial current week in the emitted `series` while excluding it from the first/last/delta/spike math (a partial "last" week would otherwise read as a fake -99% improvement). Bootstrap now resolves and prints both the 60d data window and a "Trend delta cutoff" = startofweek(curEnd), passed to the bucketer as --end. Trend KQL (60d-trend-codes/types) switched to half-open bounds and dropped the source-side partial-week filter. The per-row WoW sparklines deliberately stay on 8 complete weeks (renamed tokens to <SPARK_START>/<SPARK_END>) so no table row ends on a misleading partial dip. Docs (SKILL.md, kusto-cheatsheet, queries README, template-readme, report-template) updated to match. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 81d709d0-6563-48f0-8f7c-45ba179ee38e
shahzaibj
left a comment
There was a problem hiding this comment.
Seems like a ton of changes for a simple PR.
There was a problem hiding this comment.
Pull request overview
Updates the OCE on-call telemetry report workflow to default to a rolling 7-day window ending at start-of-day UTC “today” (with optional -EndDate override), fixing the prior Sun→Sat default that could select a future/partial window and miss the most recent days.
Changes:
- Replaces
-ReportingSundaywith-EndDateand makes bootstrap stamp the resolved window into the report header. - Updates WoW/primary KQL templates to use half-open rolling windows while keeping
startofweek()bucketing for 60-day trends (with partial-week display vs classification split). - Adds/updates validation + documentation to align authors on the new default semantics and placeholder conventions.
Reviewed changes
Copilot reviewed 26 out of 26 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| .github/skills/oncall-weekly-telemetry-report/SKILL.md | Updates skill instructions to run bootstrap without prompting and to use rolling-window defaults/terminology. |
| .github/skills/oncall-weekly-telemetry-report/assets/templates/template-readme.md | Documents bootstrap-owned header dates and the new rolling-window semantics. |
| .github/skills/oncall-weekly-telemetry-report/assets/templates/report-template.html | Adjusts template prose to reflect rolling window + updated 60-day trend wording. |
| .github/skills/oncall-weekly-telemetry-report/assets/scripts/visual-smoke.ps1 | Updates examples/output naming to <end-date> convention. |
| .github/skills/oncall-weekly-telemetry-report/assets/scripts/validate-report.ps1 | Adds rolling-window header ↔ filename consistency check. |
| .github/skills/oncall-weekly-telemetry-report/assets/scripts/summarize-attribution.js | Clarifies expected wk semantics for rolling-window buckets. |
| .github/skills/oncall-weekly-telemetry-report/assets/scripts/bucket-trends.js | Supports “include partial end week in chart but exclude from delta classification” via --include-partial-end. |
| .github/skills/oncall-weekly-telemetry-report/assets/scripts/bootstrap-report.ps1 | Implements rolling window resolution, future-date guard, header stamping, and updated collision detection. |
| .github/skills/oncall-weekly-telemetry-report/assets/scripts/agg.js | Updates docs/schema assumptions for rolling-window wk bucketing. |
| .github/skills/oncall-weekly-telemetry-report/assets/queries/wow-table-sparkline-series.kql | Keeps per-row WoW sparklines on 8 complete weeks using <SPARK_START>/<SPARK_END>. |
| .github/skills/oncall-weekly-telemetry-report/assets/queries/wow-movers.kql | Converts WoW movers query to rolling-window placeholders and half-open bounds. |
| .github/skills/oncall-weekly-telemetry-report/assets/queries/type-subcode-decomposition.kql | Converts type sub-code decomposition to rolling-window placeholders and two-bucket wk. |
| .github/skills/oncall-weekly-telemetry-report/assets/queries/reliability-auth-only.kql | Converts auth-only denominator query to rolling-window placeholders and two-bucket wk. |
| .github/skills/oncall-weekly-telemetry-report/assets/queries/README.md | Re-documents placeholder conventions (CUR_*, TREND_*, SPARK_*) and partial-week rules. |
| .github/skills/oncall-weekly-telemetry-report/assets/queries/os-version-slice.kql | Converts OS slice query to rolling-window placeholders and half-open bounds. |
| .github/skills/oncall-weekly-telemetry-report/assets/queries/latency.kql | Converts latency query to rolling-window placeholders and two-bucket wk. |
| .github/skills/oncall-weekly-telemetry-report/assets/queries/error-message-and-location.kql | Converts throw-site/message query to rolling-window placeholders and half-open bounds. |
| .github/skills/oncall-weekly-telemetry-report/assets/queries/broker-version-share.kql | Converts broker version share query to rolling-window placeholders and two-bucket wk. |
| .github/skills/oncall-weekly-telemetry-report/assets/queries/broker-version-share-wow.kql | Converts WoW snapshot query to rolling-window placeholders and half-open bounds. |
| .github/skills/oncall-weekly-telemetry-report/assets/queries/attr-union-by-dim.kql | Updates union attribution query to rolling-window placeholders and wk=iff(...) bucketing. |
| .github/skills/oncall-weekly-telemetry-report/assets/queries/attr-types-by-dim.kql | Updates per-dim type attribution query to rolling-window placeholders and wk=iff(...). |
| .github/skills/oncall-weekly-telemetry-report/assets/queries/attr-codes-by-dim.kql | Updates per-dim code attribution query to rolling-window placeholders and wk=iff(...). |
| .github/skills/oncall-weekly-telemetry-report/assets/queries/app-share.kql | Updates traffic/app share query to rolling-window placeholders and two-bucket wk. |
| .github/skills/oncall-weekly-telemetry-report/assets/queries/60d-trend-types.kql | Updates 60-day trend types query to <TREND_START>/<TREND_END> semantics (no source-side partial-week filter). |
| .github/skills/oncall-weekly-telemetry-report/assets/queries/60d-trend-codes.kql | Updates 60-day trend codes query to <TREND_START>/<TREND_END> semantics (partial-week handled in JS). |
| .github/skills/oncall-weekly-telemetry-report/assets/docs/kusto-cheatsheet.md | Adds canonical rolling-window snippet + clarifies where startofweek() still applies. |
shahzaibj
left a comment
There was a problem hiding this comment.
At the time of invoking the skill, if a user explicitly provides a different time window then will the skill handle that?
…k rename, harden stub-detection Review-fix round on the rolling-7-day-window PR: - Scrub all personal/ticket self-attribution (Fadi / AB#3683194 / feedback-date) from the skill; rewrite rationale impersonally. Legitimate report-content AB# placeholders (Likely-PRs field, code-attribution template, sample report) kept. - Rename the two-bucket `wk` column to `week` across every KQL template and every JS/PS consumer (agg.js, summarize-attribution.js, bucket-trends.js, validate-report.ps1). Dropped the now-dead `wk` schema fallbacks. Verified end-to-end: zero remaining `wk`, all three JS readers consume `week`. - Fix the SKILL.md "Resolved reporting window" example so every line derives from one today (2026-07-15): Last-7d 07-08->07-15, 60d 05-16->07-15, cutoff 07-12. - template-readme.md: Generated date is UTC by contract -> recommend a UTC formatter, stop warning against toISOString(). - report-template.html appendix: genericize hardcoded methodology dates. - validate-report.ps1: align checklist numbering (add #10 fabricated-sparkline; rolling-window header integrity is #11 in docstring, code header, and SKILL.md). - Harden bootstrap stub/collision detection: inject an OCE-UNPOPULATED-STUB sentinel; a same-day report is silently re-bootstrapped only when it still carries that sentinel AND the template's first KPI, else refuse+exit unless -Force. validate-report.ps1 fails if the sentinel is still present, so a published report can never be misclassified as a stub. - Document the override limitation in SKILL.md: only -EndDate is supported; no custom start-date or arbitrary span. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 81d709d0-6563-48f0-8f7c-45ba179ee38e
|
On the file count: defaulting to a rolling window forces every query that was Sunday-anchored or hardcoded onto the shared Happy to split the pure-doc files (queries/README.md, kusto-cheatsheet.md, template-readme.md) into a follow-up PR if you'd prefer a smaller diff here. The KQL + script edits are load-bearing for the default to work, so those need to stay together. |
|
Verified. The only override is I chose to document this limitation explicitly in SKILL.md (Inputs section) rather than silently emit a 7-day report when a user asks for something else, so we surface it up front. If we want true custom spans, a |
Second review pass on the review-fix commit flagged four issues: - bootstrap-report.ps1 .DESCRIPTION: fix the duplicated "for transparency for transparency" phrase and the unmatched quote/paren in the help text. - bucket-trends.js: `--include-partial-end` is documented as a no-op without `--end`, but displayKeep included ALL weeks when endISO was null, which re-introduced the auto-detected partial end bucket into the emitted series/JSON. Gate the partial-inclusion branch on endISO so it truly mirrors classKeep (partial stays dropped) without `--end`. Verified: no `--end` -> partial week excluded; with `--end` -> partial charted but still excluded from delta/first/last classification. - SKILL.md: the "Generated date" guidance still said local-time and warned against toISOString(); bootstrap stamps UTC ((Get-Date).ToUniversalTime()). Flip it to recommend a UTC formatter. Also fixed the matching leftover in template-readme.md step 1. - SKILL.md: drop `<PREV_END>` from the placeholder list -- no query template defines it (the baseline end is always `<CUR_START>`). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 81d709d0-6563-48f0-8f7c-45ba179ee38e
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 26 out of 26 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
.github/skills/oncall-weekly-telemetry-report/assets/templates/report-template.html:566
- The 60-day trend methodology text still hardcodes an example-specific partial-week date ("Dropped the partial start week (Mar 1)"). Since header dates are now auto-stamped per-run and the 60-day window is rolling, this hardcoded date will become stale/misleading in every newly bootstrapped report unless authors remember to hunt it down manually.
<h2 id="trend60d">📈 60-Day Trend Analysis <span class="count">— literal last 60 days ending today; final bar = current partial week</span></h2>
<div class="glossary">
<strong>Methodology:</strong> Pulled all error codes from the <code>ErrorStats</code> view over the last 9 weeks. Dropped the partial start week (Mar 1). Kept all codes whose <strong>peak weekly device count ≥ 10 K</strong>. Bucketed each 8-week series by <code>delta = (last − first) / first</code>:
<strong>regression</strong> if delta > +15% and trajectory is monotonic-ish; <strong>ephemeral spike</strong> if peak ≥ 3× mean of surrounding weeks; <strong>improvement</strong> if delta < −15%; <strong>flat</strong> otherwise. Every code in the regression list gets a spike-attribution card below.
Copilot follow-up on #447: the guard compared curEnd (a 00:00-UTC date boundary) against $nowUtc.AddHours(1). That 1-hour slack let a *future* end-date slip through -- running in the last hour before midnight UTC would accept tomorrow as -EndDate, including today's partial data and shifting the rolling window, contradicting the documented "future dates are refused." Compare date-to-date instead ([datetime]::UtcNow.Date): -EndDate == today passes (the default), -EndDate == tomorrow is refused, independent of the time of day. Verified: -EndDate <tomorrow> throws + exits non-zero before any file write; -EndDate <today> resolves and stamps normally. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 81d709d0-6563-48f0-8f7c-45ba179ee38e
|
Thanks for taking care of this! But 26 files seems huge for the kind of change i suggested. Perhaps the skill is a bit too complex, i feel this makes upkeep a little bit more difficult in the future. have we considered making this less verbose or trimming it down a bit? If we ever want to change something else about this skill or similar skills we have, will it also be this volume of file changes? |
|
Fair callout — here's the actual breakdown of the 26:
On your forward-looking question — no, future changes won't be this heavy. This PR pays a one-time centralization cost: the window is now a single control point. Changing it again (rolling 14-day, month-to-date, whatever) is an edit to the resolver in The skill's overall size is real, but it's inherent to what it does — a validated, self-contained HTML report across ~15 telemetry dimensions — not verbosity this PR introduced. If you'd like a smaller review surface here, I'm happy to pull the 4 pure-doc files into a follow-up doc-only PR so this one is code + template only. Say the word. |
Fixes AB#3683194
Feedback
From Fadi Durah's ★4 skill-effectiveness survey (Jun 2026,
oncall-weekly-telemetry-report):Root cause (repro'd on today's clock, Thu 2026-07-09)
bootstrap-report.ps1was computing "reporting Sunday" as the most recent Sunday strictly before today — which is the Sunday of the currently in-progress week. Run on a Thursday it pickedSun 2026-07-05 → Sat 2026-07-11where Saturday is 2 days in the future, so the WoW section queried a 4-day partial window and dropped the last complete week. Exactly Fadi's "missed the last 6 days" complaint.SKILL.mdthen compounded it by asking the model to confirm the Sunday with the user — the manual coax that the developer shouldn't have to do.Fix
Per the user's direction, deep rewrite: rolling
[today−7d, today)for the primary WoW view, keeping Sun-Sat weekly bucketing only for the 60-day trend (where stable weekly denominators still matter).bootstrap-report.ps1— new-EndDateparam (default: today UTC). ComputescurStart = curEnd−7d,prevStart = curEnd−14d, andtrendEnd = startofweek(curEnd). Stamps the resolved window into the<title>,<div class="meta">block, and Generated banner so header dates can never drift from what was queried (this is the ADO acceptance criterion). Refuses future end-dates. Collision fingerprint stopped keying off title/meta (which bootstrap now rewrites unconditionally) — usesfirstKpi+ size ratio only.15 KQL templates — 12 primary/WoW queries switched to half-open
[prevStart, curEnd)withwk = iff(EventInfo_Time >= curStart, curStart, prevStart); downstream JS helpers unchanged becausewkstill sorts lexicographically. The 3 60-day-trend queries keepstartofweek()bucketing; only<END>renamed to<TREND_END>with clarifiedstartofweek(today)-exclusive semantics. Placeholder audit is now consistent across all 15 files.SKILL.md— rewrote Inputs to confirm §1: do NOT ask the user for a date by default; just run bootstrap. Override via-EndDateonly when the user explicitly requests a non-default window. Filename convention<sunday>→<end-date>throughout. All KQL placeholder examples switched to the rolling-window form.validate-report.ps1— new check Migrate to AndroidX #11 asserts the meta-line "Last 7 days" dates are self-consistent with the filename's end-date. Catches any hand-edit that broke the auto-stamp, or a stale template stub being published fresh.Docs —
template-readme.md§ Date fields rewritten (bootstrap owns every date field; author never edits them).kusto-cheatsheet.mdgains § 3 Rolling 7-day WoW window with the canonicallet curStart/curEnd/prevStarttemplate; the pre-existingstartofweek()-alignment section is now scoped explicitly to the 60-day trend.Breaking changes (intentional)
bootstrap-report.ps1:-ReportingSundayparameter removed; use-EndDate. The old parameter name encoded the exact semantic mismatch that caused the bug — keeping it would have preserved the footgun.oncall-wow-report-<end-date>.html(was<sunday>.html). Old on-disk reports are unaffected.Verification
[2026-07-02, 2026-07-09).-EndDate 2026-07-02→[2026-06-25, 2026-07-02).-EndDate 2027-01-01→ refused (future-date guard).-Force.<START>/<END>/<CURR_*>/<PREV_WEEK>references remain.