lightsoutAlpha

private-helper-colocation

a helper a second file needs while it still sits unexported in the first

Agent checkadvisory by defaultbasecode

The argument

Private Helpers May Co-Locate

A non-exported helper may live in the file of the export it serves when both hold: (1) no export keyword, (2) called only from this file. The file acts as a module: the export is the public API, helpers are compiler-enforced internals, covered through the export's tests. The moment a second file needs the helper, it gets exported — and exported means its own file. The bright line stays mechanical: export keyword → own file.

interface Params {
	records: ReportRecord[];
}

// Private helper: inline object type, inferred return
const sumTotals = ({ records }: { records: ReportRecord[] }) => {
	return records.reduce((total, record) => total + record.amount, 0);
};

// Export: Params interface + declared return type
export const buildReportSummary = ({ records }: Params): { total: number } => {
	return { total: sumTotals({ records }) };
};

If a helper's branches cannot be reached through the export's inputs, that branch is dead code — delete it. If covering a helper through the export is genuinely impractical (combinatorial inputs), the helper has earned promotion to its own file with its own tests.

The proof

fail
interface Params {
	records: Array<{ amount: number }>;
}

// The same helper, retyped — the moment a second file needed it, it had earned
// an export and a file of its own.
const sumTotals = ({ records }: { records: Array<{ amount: number }> }) => records.reduce((total, record) => total + record.amount, 0);

export const buildInvoiceTotals = ({ records }: Params): { total: number } => ({ total: sumTotals({ records }) });
passsrc/reporting/buildReportSummary.ts
interface Params {
	records: Array<{ amount: number }>;
}

// Called only from this file, so it stays a compiler-enforced internal and is
// covered through the export's own tests.
const sumTotals = ({ records }: { records: Array<{ amount: number }> }) => records.reduce((total, record) => total + record.amount, 0);

export const buildReportSummary = ({ records }: Params): { total: number } => ({ total: sumTotals({ records }) });

Turn it down

Both lines go in your lightsout.config.json.

"standards-checks": { "private-helper-colocation": "advisory" }
"standards-checks": { "private-helper-colocation": "off" }