# core/steps/canon.step.ts

> 79 lines of code and 16 definitions.

Tree: GovLab Quality
Language: typescript
Layer: application
Canonical: https://banes-lab.com/anatomy/quality#file-quality-core-steps-canon-step-ts
Source text: https://banes-lab.com/source/quality/core/steps/canon.step.ts.txt

Listed in [core/steps](https://banes-lab.com/api/source/quality/core/steps.md), before [core/steps/catalog.step.ts](https://banes-lab.com/source/quality/core/steps/catalog.step.ts.md).

## Definitions

- `normalizeFidelity` (lexical_declaration, line 27)
- `isFidelity` (lexical_declaration, line 23)
- `surfaceOf` (lexical_declaration, line 34)
- `settingOf` (lexical_declaration, line 38)
- `rowOf` (lexical_declaration, line 49)
- `SETTINGS_FILE` (lexical_declaration, line 17)
- `ROWS_FILE` (lexical_declaration, line 18)
- `TOKENS_FILE` (lexical_declaration, line 19)
- `APPROX` (lexical_declaration, line 20)
- `FLOOR_FIDELITY` (lexical_declaration, line 21)
- `mapping` (lexical_declaration, line 69)
- `owned` (lexical_declaration, line 70)
- `settings` (lexical_declaration, line 71)
- `rows` (lexical_declaration, line 72)
- `tokens` (lexical_declaration, line 73)
- `perTool` (lexical_declaration, line 76)

## Contained in

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

## Linked from

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

## Source

```typescript
import {
    CONCEPT_SURFACE,
    DEFAULT_PROVENANCE,
    FIDELITY_LEVELS,
    FORMAT_DIMENSION,
    LAYOUT_SURFACE,
    OWNED_BY_VALUE_SETTINGS,
    TOGGLE_VALUE_TYPE,
} from "#configuration/constants/canon.constants";
import type { CanonicalSettingRecord, Fidelity, MappingConcept, MappingEntry, MappingRow } from "#types/canon.types";
import type { EmitTokens } from "#types/emitter.types";
import { absolutePath } from "@ssot/paths";
import { defineStep } from "#core/registries/step.registry";
import { loadKnobConcepts } from "#core/loaders/knob.loader";
import { mappingConcepts } from "#core/converters/canon.concept.converter";

const SETTINGS_FILE = "canonical-settings.generated.json";
const ROWS_FILE = "mapping-rows.generated.json";
const TOKENS_FILE = "emit-tokens.generated.json";
const APPROX = "approx";
const FLOOR_FIDELITY = "advisory";

const isFidelity = function isFidelity(value: string | null): value is Fidelity {
    return value !== null && FIDELITY_LEVELS.has(value);
};

const normalizeFidelity = function normalizeFidelity(value: string | null): Fidelity {
    if (value === APPROX) {
        return "approximate";
    }
    return isFidelity(value) ? value : FLOOR_FIDELITY;
};

const surfaceOf = function surfaceOf(id: string, dimension: string): string {
    return dimension === FORMAT_DIMENSION ? LAYOUT_SURFACE : (CONCEPT_SURFACE.get(id) ?? id);
};

const settingOf = function settingOf(id: string, concept: MappingConcept): CanonicalSettingRecord {
    return {
        default: null,
        dimension: concept.dimension,
        id,
        kind: concept.valueType === TOGGLE_VALUE_TYPE ? "rule-intent" : "value",
        surface: surfaceOf(id, concept.dimension),
        valueType: concept.valueType,
    };
};

const rowOf = function rowOf(id: string, entry: MappingEntry): MappingRow {
    return {
        canonicalId: id,
        default: entry.default ?? null,
        fidelity: normalizeFidelity(entry.fidelity),
        fixed: entry.fixed ?? false,
        knob: entry.knob,
        langs: Array.isArray(entry.lang) ? entry.lang : [entry.lang],
        provenance: { source: entry.provenance ?? DEFAULT_PROVENANCE, toolVersion: "" },
        ruleCount: entry.ruleCount,
        tool: entry.tool,
        verified: entry.verified,
    };
};

defineStep({
    gives: [],
    name: "canon",
    needs: ["catalog", "concepts"],
    run: async (state, writer) => {
        const mapping = mappingConcepts(state.catalog ?? [], state.concepts ?? [], loadKnobConcepts());
        const owned = [...mapping].filter(([id]) => !OWNED_BY_VALUE_SETTINGS.has(id));
        const settings = owned.map(([id, concept]) => settingOf(id, concept));
        const rows = owned.flatMap(([id, concept]) => concept.entries.map((entry) => rowOf(id, entry)));
        const tokens: EmitTokens = {};
        for (const [id, concept] of owned) {
            for (const entry of concept.entries) {
                const perTool = tokens[entry.tool] ?? {};
                perTool[id] = { knob: entry.knob, ruleIds: entry.ruleIds };
                tokens[entry.tool] = perTool;
            }
        }
        await writer.json(absolutePath("govlab.quality.generated", SETTINGS_FILE), { settings });
        await writer.json(absolutePath("govlab.quality.generated", ROWS_FILE), { rows });
        await writer.json(absolutePath("govlab.quality.generated", TOKENS_FILE), { tokens });
        return {};
    },
});
```
