fix(audit): require integer rolling retention keep limits
Validate keepPerFamily/--keep-per-family as non-negative integers, remove silent flooring, add regression coverage, and sync runbook/docs wording.
This commit is contained in:
@@ -29,13 +29,19 @@ function isoDateTagNow(): string {
|
||||
return new Date().toISOString().slice(0, 10);
|
||||
}
|
||||
|
||||
function parseOptionalNumber(raw: string | undefined, flag: string): number | undefined {
|
||||
function parseOptionalInteger(raw: string | undefined, flag: string): number | undefined {
|
||||
if (!raw) {
|
||||
return undefined;
|
||||
}
|
||||
const parsed = Number(raw);
|
||||
if (!Number.isFinite(parsed)) {
|
||||
throw new Error(`Invalid ${flag} value "${raw}". Expected a number.`);
|
||||
throw new Error(`Invalid ${flag} value "${raw}". Expected an integer.`);
|
||||
}
|
||||
if (!Number.isInteger(parsed)) {
|
||||
throw new Error(`Invalid ${flag} value "${raw}". Expected an integer.`);
|
||||
}
|
||||
if (parsed < 0) {
|
||||
throw new Error(`${flag} must be greater than or equal to 0.`);
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
@@ -94,7 +100,7 @@ async function main(): Promise<void> {
|
||||
}
|
||||
|
||||
const artifactsDir = resolve(values['artifacts-dir'] ?? 'docs/plans/artifacts');
|
||||
const keepPerFamily = parseOptionalNumber(values['keep-per-family'], '--keep-per-family') ?? 8;
|
||||
const keepPerFamily = parseOptionalInteger(values['keep-per-family'], '--keep-per-family') ?? 8;
|
||||
const apply = Boolean(values.apply);
|
||||
const format = values.format ?? 'text';
|
||||
const reportTag = values['report-tag'] ?? isoDateTagNow();
|
||||
@@ -128,7 +134,7 @@ async function main(): Promise<void> {
|
||||
const payload = {
|
||||
generated_at: new Date().toISOString(),
|
||||
artifacts_dir: artifactsDir,
|
||||
keep_per_family: Math.floor(keepPerFamily),
|
||||
keep_per_family: keepPerFamily,
|
||||
apply,
|
||||
report_tag: reportTag,
|
||||
reports: {
|
||||
@@ -138,7 +144,7 @@ async function main(): Promise<void> {
|
||||
plan,
|
||||
};
|
||||
const jsonOutput = JSON.stringify(payload, null, 2);
|
||||
const textOutput = renderText(plan, artifactsDir, Math.floor(keepPerFamily), apply);
|
||||
const textOutput = renderText(plan, artifactsDir, keepPerFamily, apply);
|
||||
|
||||
if (summaryJsonOut) {
|
||||
await writeTextFile(summaryJsonOut, jsonOutput);
|
||||
|
||||
Reference in New Issue
Block a user