# core/validators/algorithm.derivation.validator.ts

> 56 lines of code and 13 definitions.

Tree: GovLab Context
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/context#file-context-core-validators-algorithm-derivation-validator-ts
Source text: https://banes-lab.com/source/context/core/validators/algorithm.derivation.validator.ts.txt

Listed in [core/validators](https://banes-lab.com/api/source/context/core/validators.md), before [core/validators/algorithm.reason.validator.ts](https://banes-lab.com/source/context/core/validators/algorithm.reason.validator.ts.md).

## Definitions

- `isKernelContract` (lexical_declaration, line 50, exported)
- `derivationMapDefectsOf` (lexical_declaration, line 54, exported)
- `entryDefect` (lexical_declaration, line 21)
- `derivationMapDefect` (lexical_declaration, line 31)
- `DerivationFaces` (interface_declaration, line 9)
- `MapCheck` (interface_declaration, line 13)
- `MANDATORY_STAGES` (lexical_declaration, line 19)
- `map` (lexical_declaration, line 36)
- `check` (lexical_declaration, line 40)
- `first` (lexical_declaration, line 41)
- `covered` (lexical_declaration, line 45)
- `missing` (lexical_declaration, line 46)
- `defect` (lexical_declaration, line 60, exported)

## Contained in

- [core/validators](https://banes-lab.com/anatomy/context/folder-context-core-validators.md)

## Uses

- [configuration/strings/algorithm.strings.ts](https://banes-lab.com/source/context/configuration/strings/algorithm.strings.ts.md)

## Used by

- [core/validators/algorithm.reason.validator.ts](https://banes-lab.com/source/context/core/validators/algorithm.reason.validator.ts.md)

## Linked from

- [configuration/strings](https://banes-lab.com/anatomy/context/folder-context-configuration-strings.md)
- [core/validators](https://banes-lab.com/anatomy/context/folder-context-core-validators.md)

## Source

```typescript
import type { Contract, DerivationMapEntry } from "#types/algorithm.types";
import {
    derivationSelfMapped,
    derivationUnknownRecord,
    derivationUnknownStage,
    derivationUnstaged,
} from "#configuration/strings/algorithm.strings";

interface DerivationFaces {
    algo: { get: (id: string) => unknown };
}

interface MapCheck {
    stages: ReadonlyMap<string, string>;
    faces: DerivationFaces;
    contractId: string;
}

const MANDATORY_STAGES = ["verify"];

const entryDefect = function entryDefect(entry: DerivationMapEntry, check: MapCheck): string | null {
    if (!check.stages.has(entry.stage)) {
        return derivationUnknownStage(entry.stage);
    }
    if (entry.record === check.contractId) {
        return derivationSelfMapped(entry.stage);
    }
    return check.faces.algo.get(entry.record) === null ? derivationUnknownRecord(entry.record) : null;
};

const derivationMapDefect = function derivationMapDefect(
    contract: Contract,
    stages: ReadonlyMap<string, string>,
    faces: DerivationFaces,
): string | null {
    const map = contract.derivationMap ?? [];
    if (map.length === 0) {
        return null;
    }
    const check: MapCheck = { contractId: contract.id, faces, stages };
    const first = map.map((entry) => entryDefect(entry, check)).find((defect) => defect !== null);
    if (first !== undefined) {
        return first;
    }
    const covered = new Set(map.map((entry) => entry.stage));
    const missing = MANDATORY_STAGES.filter((stage) => !covered.has(stage));
    return missing.length > 0 ? derivationUnstaged(missing) : null;
};

export const isKernelContract = function isKernelContract(contract: Contract): boolean {
    return Array.isArray(contract.derivationMap) && contract.derivationMap.length > 0;
};

export const derivationMapDefectsOf = function derivationMapDefectsOf(
    contracts: readonly Contract[],
    stages: ReadonlyMap<string, string>,
    faces: DerivationFaces,
): { id: string; reason: string }[] {
    return contracts.flatMap((contract) => {
        const defect = derivationMapDefect(contract, stages, faces);
        return defect === null ? [] : [{ id: contract.id, reason: defect }];
    });
};
```
