# tools/core/steps/source.step.ts

> 134 lines of code and 26 definitions.

Tree: Coordination tree
Language: typescript
Layer: application
Canonical: https://banes-lab.com/anatomy/coordination#file-coordination-tools-core-steps-source-step-ts
Source text: https://banes-lab.com/assets/sources/source.6e1cae47f92dbbf8f6a69a2c6edaed247c9429ddfcc4165a3940ec9be77ccf36.generated.txt

## Definitions

- `isVendored` (lexical_declaration, line 18, exported)
- `codeFiles` (lexical_declaration, line 38, exported)
- `cleanStage` (lexical_declaration, line 76, exported)
- `cleanSources` (function_declaration, line 119, exported)
- `CODE_EXTENSIONS` (lexical_declaration, line 14, exported)
- `CODE_ROOTS` (lexical_declaration, line 16)
- `leading` (lexical_declaration, line 19, exported)
- `CleanedFile` (interface_declaration, line 23, exported)
- `CleanResult` (interface_declaration, line 29, exported)
- `taxonomy` (lexical_declaration, line 39, exported)
- `roots` (lexical_declaration, line 40, exported)
- `seen` (lexical_declaration, line 53, exported)
- `out` (lexical_declaration, line 54, exported)
- `relative` (lexical_declaration, line 62, exported)
- `INVARIANT` (lexical_declaration, line 74)
- `cleaned` (lexical_declaration, line 84, exported)
- `files` (lexical_declaration, line 120, exported)
- `refused` (lexical_declaration, line 121, exported)
- `removed` (lexical_declaration, line 122, exported)
- `kept` (lexical_declaration, line 123, exported)
- `paths` (lexical_declaration, line 125, exported)
- `absolute` (lexical_declaration, line 128, exported)
- `source` (lexical_declaration, line 129, exported)
- `spans` (lexical_declaration, line 130, exported)
- `result` (lexical_declaration, line 138, exported)
- `outcome` (lexical_declaration, line 144, exported)

## Uses

- [tools/core/predicates/comment.predicate.ts](https://banes-lab.com/source/coordination/tools/core/predicates/comment.predicate.ts.md)
- [tools/core/reporters/rule.reporter.ts](https://banes-lab.com/source/coordination/tools/core/reporters/rule.reporter.ts.md)
- [tools/core/resolvers/artifact.resolver.ts](https://banes-lab.com/source/coordination/tools/core/resolvers/artifact.resolver.ts.md)

## Source

```typescript
import { type CommentSpan, commentsOf, isAttribution, stripComments } from "../normalizers/source.normalizer.ts";
import type { StepOptions, StepOutcome } from "../types/rule.types.ts";

import { existsSync, readFileSync } from "node:fs";
import { toPosix, walk } from "../iterators/file.iterator.ts";
import { SURFACE_ROOT } from "../constants/path.constants.ts";
import { loadTaxonomy } from "../resolvers/taxonomy.resolver.ts";
import { resolve } from "node:path";
import { resolveArtifactRoots } from "../resolvers/artifact.resolver.ts";
import { slotList } from "../../../config/surface.config.ts";
import { writeRepair } from "../writers/repair.writer.ts";
import { writeRuleReport } from "../reporters/rule.reporter.ts";

export const CODE_EXTENSIONS: readonly string[] = slotList("convention", "code_extensions");

const CODE_ROOTS = [SURFACE_ROOT];

export const isVendored = function isVendored(spans: readonly CommentSpan[]): boolean {
    const leading = spans[0];
    return leading !== undefined && isAttribution(leading.text);
};

export interface CleanedFile {
    readonly path: string;
    readonly removed: number;
    readonly kept: number;
}

export interface CleanResult {
    readonly files: readonly CleanedFile[];
    readonly reached: readonly string[];
    readonly refused: readonly string[];
    readonly removed: number;
    readonly kept: number;
    readonly scanned: number;
}

export const codeFiles = function codeFiles(repoRoot: string): string[] {
    const taxonomy = loadTaxonomy();
    const roots: string[] = [...Object.keys(taxonomy.containers), ...Object.keys(taxonomy.specialContainers)];

    for (const root of resolveArtifactRoots(repoRoot, taxonomy)) {
        if (root.unresolved === null) {
            roots.push(root.path);
        }
    }
    for (const root of CODE_ROOTS) {
        if (existsSync(resolve(repoRoot, root))) {
            roots.push(root);
        }
    }

    const seen = new Set<string>();
    const out: string[] = [];

    for (const root of roots) {
        for (const file of walk({
            extensions: [...CODE_EXTENSIONS],
            ignored: taxonomy.ignored,
            root: resolve(repoRoot, root),
        })) {
            const relative = toPosix(repoRoot, file);
            if (seen.has(relative)) {
                continue;
            }
            seen.add(relative);
            out.push(relative);
        }
    }

    return out.sort();
};

const INVARIANT = "authored code carries no comments";

export const cleanStage = function cleanStage(options: StepOptions): StepOutcome {
    if (options.bypass.includes("clean")) {
        return {
            findings: [],
            stage: { bypassed: true, findings: 0, healed: 0, invariant: INVARIANT, rule: "clean", stage: "meta" },
        };
    }

    const cleaned = cleanSources(options.repoRoot, options.fix, options.scope);

    writeRuleReport(options.repoRoot, "clean", {
        authoritative: options.authoritative,
        derivations: {
            containment:
                "every repair passes the restricted writer, which refuses a path outside the scope this run DECLARED — " +
                "so containment is answered at one function rather than by a witness nobody holds for a repair scattered " +
                "across source, and a refusal is reported here rather than the write landing and being reported afterwards",
            reached: [...cleaned.reached],
            refusedAsOutsideDeclaredScope: [...cleaned.refused],
        },
        findings: [],
        healed: cleaned.files.map((file) => `${file.path}: ${String(file.removed)} removed`),
        invariant: INVARIANT,
        rule: "clean",
        scanned: cleaned.scanned,
        scope: options.scope,
        stage: "meta",
        verdict: "pass",
    });

    return {
        findings: [],
        stage: {
            bypassed: false,
            findings: 0,
            healed: cleaned.files.length,
            invariant: INVARIANT,
            rule: "clean",
            stage: "meta",
        },
    };
};

export function cleanSources(repoRoot: string, apply: boolean, declared = ""): CleanResult {
    const files: CleanedFile[] = [];
    const refused: string[] = [];
    let removed = 0;
    let kept = 0;

    const paths = codeFiles(repoRoot);

    for (const path of paths) {
        const absolute = resolve(repoRoot, path);
        const source = readFileSync(absolute, "utf8");
        const spans = commentsOf(path, source);
        if (spans.length === 0) {
            continue;
        }
        if (isVendored(spans)) {
            continue;
        }

        const result = stripComments(source, spans);
        if (result.removed === 0) {
            continue;
        }

        if (apply && result.text !== source) {
            const outcome = writeRepair({ declared, repoRoot }, path, result.text);
            if (!outcome.written) {
                refused.push(path);
                continue;
            }
        }

        files.push({ kept: result.kept, path, removed: result.removed });
        removed += result.removed;
        kept += result.kept;
    }

    return { files, kept, reached: paths, refused, removed, scanned: paths.length };
}
```
