fix(legacy-meter): capture evidence over 7 days, not an 8-hour band
capture_legacy_meter_evidence.py fell back to hours=8 whenever --days was omitted, and --hours itself defaulted to 8. Every unattended capture sampled 06:00Z-14:00Z while writing a file named weekly-review with cadence: weekly. 39 of 40 captures ran this way; only 2026-07-08 used a true 7-day window. Calls outside the band were never sampled, so interfaces with live callers reported as retirement candidates -- GET /tasks/?workstream_id was flagged on 2026-08-19 despite traffic on 2026-08-18. Default the script to days=7; keep --hours for spot checks, documented as not retirement evidence. Adds corrected capture for 2026-08-20 and records the residual gap (candidate rule ignores last_seen_at) against STATE-WP-0079-T05. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
5fe38fa9d8
commit
be7f2632c3
4 changed files with 1793 additions and 22 deletions
|
|
@ -71,10 +71,20 @@ def _retire_interfaces(base: str, keys: list[str]) -> list[dict]:
|
|||
return retired
|
||||
|
||||
|
||||
DEFAULT_REVIEW_DAYS = 7
|
||||
|
||||
|
||||
def _review_query(*, days: int | None, hours: int | None) -> str:
|
||||
if days is not None:
|
||||
return f"days={days}"
|
||||
return f"hours={hours or 8}"
|
||||
"""Build the review-window query.
|
||||
|
||||
Defaults to a 7-day window to match the ``weekly-review`` endpoint and the
|
||||
``cadence: weekly`` label in the payload. An hours-scoped window only
|
||||
samples part of each day, so an interface called outside that band reads as
|
||||
unused and is falsely reported as a retirement candidate.
|
||||
"""
|
||||
if hours is not None:
|
||||
return f"hours={hours}"
|
||||
return f"days={days or DEFAULT_REVIEW_DAYS}"
|
||||
|
||||
|
||||
def capture(
|
||||
|
|
@ -101,10 +111,10 @@ def capture(
|
|||
"retired_interfaces": retired,
|
||||
"weekly_review": review,
|
||||
}
|
||||
if days is not None:
|
||||
payload["days"] = days
|
||||
if hours is not None:
|
||||
payload["hours"] = hours
|
||||
else:
|
||||
payload["hours"] = hours or 8
|
||||
payload["days"] = days or DEFAULT_REVIEW_DAYS
|
||||
|
||||
if dry_run:
|
||||
print(json.dumps(payload, indent=2))
|
||||
|
|
@ -124,14 +134,15 @@ def main() -> None:
|
|||
parser.add_argument(
|
||||
"--hours",
|
||||
type=int,
|
||||
default=8,
|
||||
help="Review window in hours (default: 8; used when --days is omitted)",
|
||||
default=None,
|
||||
help="Review window in hours; only samples part of each day — use for "
|
||||
"spot checks, never as retirement evidence",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--days",
|
||||
type=int,
|
||||
default=None,
|
||||
help="Review window in days (weekly cadence; overrides --hours)",
|
||||
help=f"Review window in days (default: {DEFAULT_REVIEW_DAYS}, weekly cadence)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--api-base",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue