Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | 5x 5x 5x 24x 24x 31x 22x 22x 22x 2x 26x 25x 26x 26x 15x 15x 24x 24x 24x 22x 15x 14x | // SPDX-FileCopyrightText: 2024-2026 Hack23 AB
// SPDX-License-Identifier: Apache-2.0
/**
* @module MCP/ep/staleness
* @description Procedures-feed staleness detection for EP MCP tools.
*/
/**
* Staleness threshold for procedures feed responses.
* Any response where the newest dated item is earlier than this year is treated as stale.
* See `.github/prompts/07-mcp-reference.md` §11 row #5.
*/
export const PROCEDURES_STALENESS_YEAR_THRESHOLD = 2020;
/**
* Minimum plausible year for EP procedure dates.
* The European Parliament was established in 1952; anything earlier is malformed.
*/
export const MIN_VALID_PROCEDURE_YEAR = 1952;
/**
* Maximum plausible year for EP procedure dates.
* Used as an upper sanity bound to reject obviously malformed 4-digit strings.
*/
export const MAX_VALID_PROCEDURE_YEAR = 2100;
/**
* Extract the first valid 4-digit year from an EP procedure item.
* Checks `dateInitiated`, then `dateLastActivity`, then the first 4 characters
* of `reference` (e.g. `"1972/0001(SYN)"`), returning `NaN` when none found.
*
* @param obj - Procedure item as a plain record
* @returns 4-digit year number, or `NaN` if no valid year field exists
*/
export function extractProcedureItemYear(obj: Record<string, unknown>): number {
const dateFields = [obj['dateInitiated'], obj['dateLastActivity'], obj['reference']];
for (const field of dateFields) {
if (typeof field !== 'string' || field.length < 4) continue;
const year = Number(field.slice(0, 4));
Eif (
!Number.isNaN(year) &&
year >= MIN_VALID_PROCEDURE_YEAR &&
year <= MAX_VALID_PROCEDURE_YEAR
) {
return year;
}
}
return NaN;
}
/**
* Detect whether a procedures feed response is in a stale historical-tail mode —
* i.e., the newest dated item is older than
* {@link PROCEDURES_STALENESS_YEAR_THRESHOLD}.
*
* During parliamentary recesses the EP procedures/feed endpoint may return historical
* archive data in ID order rather than current procedures. This function detects that
* condition so callers can emit a `🟡 procedures-feed: recess mode` audit row instead
* of treating the response as usable current data.
*
* Date extraction order per item: `dateInitiated`, then `dateLastActivity`, then
* `reference` (first four characters). The first valid 4-digit year found in the
* range `[1952, 2100]` is used.
*
* Returns `false` when the payload is `undefined`, contains no items, or has no
* parseable years.
*
* @param payload - Parsed procedures feed payload
* @returns `true` when the newest dated item is earlier than `PROCEDURES_STALENESS_YEAR_THRESHOLD`
*/
export function detectProceduresFeedStaleTail(
payload: Record<string, unknown> | undefined
): boolean {
if (!payload) return false;
const rawItems = payload['items'] ?? payload['procedures'];
const items = Array.isArray(rawItems) ? rawItems : [];
if (items.length === 0) return false;
const years: number[] = [];
for (const item of items) {
Iif (!item || typeof item !== 'object') continue;
const year = extractProcedureItemYear(item as Record<string, unknown>);
if (!Number.isNaN(year)) {
years.push(year);
}
}
if (years.length === 0) return false;
return Math.max(...years) < PROCEDURES_STALENESS_YEAR_THRESHOLD;
}
|