fix(audit): expand home paths across phase0 CLI scripts

Apply HOME-based ~ expansion to summarize/drift/prune audit scripts for input/output path flags to match capture behavior and avoid literal ~/ path bugs. Architecture/protocol diagrams reviewed; no updates needed for this path-resolution change.
This commit is contained in:
William Valentin
2026-02-27 13:30:08 -08:00
parent c91262ac30
commit 576b11106f
4 changed files with 57 additions and 9 deletions
+13
View File
@@ -604,6 +604,19 @@
], ],
"test_status": "pnpm typecheck + node --import tsx/esm scripts/prune-phase0-baseline-artifacts.ts --artifacts-dir <missing-dir> --format json passing" "test_status": "pnpm typecheck + node --import tsx/esm scripts/prune-phase0-baseline-artifacts.ts --artifacts-dir <missing-dir> --format json passing"
}, },
"phase0-live-baseline-home-path-expansion-consistency": {
"status": "completed",
"date": "2026-02-27",
"updated": "2026-02-27",
"summary": "Added `~` home-path expansion consistency across phase-0 summarize/drift/prune CLIs for audit/artefact path flags (`--audit`, `--artifacts-dir`, `--summary-*-out`, `--out`) to match capture script behavior.",
"files_modified": [
"scripts/summarize-phase0-baseline.ts",
"scripts/check-phase0-baseline-backend-drift.ts",
"scripts/prune-phase0-baseline-artifacts.ts",
"docs/plans/state.json"
],
"test_status": "pnpm typecheck + HOME=/tmp path-expansion smoke checks passing"
},
"phase0-instrumentation-ticket-checklist": { "phase0-instrumentation-ticket-checklist": {
"status": "completed", "status": "completed",
"date": "2026-02-25", "date": "2026-02-25",
+15 -4
View File
@@ -176,6 +176,17 @@ function formatFreshnessHours(value: number | null): string {
return `${Math.round(value * 100) / 100}`; return `${Math.round(value * 100) / 100}`;
} }
function expandHomePath(pathValue: string): string {
if (!pathValue.startsWith('~')) {
return pathValue;
}
const home = process.env.HOME;
if (!home) {
return pathValue;
}
return resolve(home, pathValue.slice(1));
}
async function writeOutput(pathValue: string, output: string): Promise<void> { async function writeOutput(pathValue: string, output: string): Promise<void> {
await mkdir(dirname(pathValue), { recursive: true }); await mkdir(dirname(pathValue), { recursive: true });
await writeFile(pathValue, `${output}\n`, 'utf8'); await writeFile(pathValue, `${output}\n`, 'utf8');
@@ -370,7 +381,7 @@ async function main(): Promise<void> {
return; return;
} }
const artifactsDir = resolve(values['artifacts-dir'] ?? 'docs/plans/artifacts'); const artifactsDir = resolve(expandHomePath(values['artifacts-dir'] ?? 'docs/plans/artifacts'));
const backends = parseBackends(values.backend); const backends = parseBackends(values.backend);
const candidateTag = values.tag const candidateTag = values.tag
? normalizeArtifactTag(values.tag, '--tag') ? normalizeArtifactTag(values.tag, '--tag')
@@ -388,12 +399,12 @@ async function main(): Promise<void> {
const defaultBaseName = resolve(artifactsDir, `phase0_baseline_live_backend_drift_${reportTag}`); const defaultBaseName = resolve(artifactsDir, `phase0_baseline_live_backend_drift_${reportTag}`);
const summaryJsonOut = values['summary-json-out'] const summaryJsonOut = values['summary-json-out']
? resolve(values['summary-json-out']) ? resolve(expandHomePath(values['summary-json-out']))
: writeDefaultArtifacts : writeDefaultArtifacts
? `${defaultBaseName}.json` ? `${defaultBaseName}.json`
: undefined; : undefined;
const summaryMdOut = values['summary-md-out'] const summaryMdOut = values['summary-md-out']
? resolve(values['summary-md-out']) ? resolve(expandHomePath(values['summary-md-out']))
: writeDefaultArtifacts : writeDefaultArtifacts
? `${defaultBaseName}.md` ? `${defaultBaseName}.md`
: undefined; : undefined;
@@ -497,7 +508,7 @@ async function main(): Promise<void> {
} }
if (values.out) { if (values.out) {
await writeOutput(resolve(values.out), output); await writeOutput(resolve(expandHomePath(values.out)), output);
} else { } else {
process.stdout.write(`${output}\n`); process.stdout.write(`${output}\n`);
} }
+14 -3
View File
@@ -30,6 +30,17 @@ function isoDateTagNow(): string {
return new Date().toISOString().slice(0, 10); return new Date().toISOString().slice(0, 10);
} }
function expandHomePath(pathValue: string): string {
if (!pathValue.startsWith('~')) {
return pathValue;
}
const home = process.env.HOME;
if (!home) {
return pathValue;
}
return resolve(home, pathValue.slice(1));
}
function parseOptionalInteger(raw: string | undefined, flag: string): number | undefined { function parseOptionalInteger(raw: string | undefined, flag: string): number | undefined {
if (!raw) { if (!raw) {
return undefined; return undefined;
@@ -111,7 +122,7 @@ async function main(): Promise<void> {
return; return;
} }
const artifactsDir = resolve(values['artifacts-dir'] ?? 'docs/plans/artifacts'); const artifactsDir = resolve(expandHomePath(values['artifacts-dir'] ?? 'docs/plans/artifacts'));
const keepPerFamily = parseOptionalInteger(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 apply = Boolean(values.apply);
const format = values.format ?? 'text'; const format = values.format ?? 'text';
@@ -124,12 +135,12 @@ async function main(): Promise<void> {
const defaultBaseName = resolve(artifactsDir, `phase0_baseline_live_prune_${reportTag}`); const defaultBaseName = resolve(artifactsDir, `phase0_baseline_live_prune_${reportTag}`);
const summaryJsonOut = values['summary-json-out'] const summaryJsonOut = values['summary-json-out']
? resolve(values['summary-json-out']) ? resolve(expandHomePath(values['summary-json-out']))
: writeDefaultArtifacts : writeDefaultArtifacts
? `${defaultBaseName}.json` ? `${defaultBaseName}.json`
: undefined; : undefined;
const summaryMdOut = values['summary-md-out'] const summaryMdOut = values['summary-md-out']
? resolve(values['summary-md-out']) ? resolve(expandHomePath(values['summary-md-out']))
: writeDefaultArtifacts : writeDefaultArtifacts
? `${defaultBaseName}.md` ? `${defaultBaseName}.md`
: undefined; : undefined;
+15 -2
View File
@@ -1,6 +1,7 @@
#!/usr/bin/env node #!/usr/bin/env node
import { writeFile } from 'node:fs/promises'; import { writeFile } from 'node:fs/promises';
import { resolve } from 'node:path';
import { parseArgs } from 'node:util'; import { parseArgs } from 'node:util';
import { queryAuditLogs } from '../src/audit/export.js'; import { queryAuditLogs } from '../src/audit/export.js';
import { import {
@@ -59,6 +60,17 @@ function parseCsv(value: string | undefined): string[] | undefined {
return values.length > 0 ? values : undefined; return values.length > 0 ? values : undefined;
} }
function expandHomePath(pathValue: string): string {
if (!pathValue.startsWith('~')) {
return pathValue;
}
const home = process.env.HOME;
if (!home) {
return pathValue;
}
return resolve(home, pathValue.slice(1));
}
function parseOptionalNumber(raw: string | undefined, flag: string): number | undefined { function parseOptionalNumber(raw: string | undefined, flag: string): number | undefined {
if (!raw) { if (!raw) {
return undefined; return undefined;
@@ -148,7 +160,8 @@ async function main(): Promise<void> {
const startTime = parseTime(values.since, '--since'); const startTime = parseTime(values.since, '--since');
const endTime = parseTime(values.until, '--until'); const endTime = parseTime(values.until, '--until');
const events = await queryAuditLogs(values.audit, { const auditPath = expandHomePath(values.audit);
const events = await queryAuditLogs(auditPath, {
start_time: startTime, start_time: startTime,
end_time: endTime, end_time: endTime,
event_types: [...DEFAULT_EVENT_TYPES], event_types: [...DEFAULT_EVENT_TYPES],
@@ -170,7 +183,7 @@ async function main(): Promise<void> {
: renderPhase0BaselineMarkdown(summary, summaryOptions); : renderPhase0BaselineMarkdown(summary, summaryOptions);
if (values.out) { if (values.out) {
await writeFile(values.out, `${output}\n`, 'utf-8'); await writeFile(expandHomePath(values.out), `${output}\n`, 'utf-8');
} else { } else {
process.stdout.write(`${output}\n`); process.stdout.write(`${output}\n`);
} }