# core/fragment/eslint/no-inline-context-literal.eslint.rule.ts

> 46 lines of code and 8 definitions.

Tree: GovLab Quality
Language: typescript
Canonical: https://banes-lab.com/anatomy/quality#file-quality-core-fragment-eslint-no-inline-context-literal-eslint-rule-ts
Source text: https://banes-lab.com/source/quality/core/fragment/eslint/no-inline-context-literal.eslint.rule.ts.txt

Listed in [core/fragment/eslint](https://banes-lab.com/api/source/quality/core/fragment/eslint.md), after [core/fragment/eslint/no-hardcoded-context-token.eslint.rule.ts](https://banes-lab.com/source/quality/core/fragment/eslint/no-hardcoded-context-token.eslint.rule.ts.md) and before [core/fragment/eslint/require-fragment-metadata.eslint.rule.ts](https://banes-lab.com/source/quality/core/fragment/eslint/require-fragment-metadata.eslint.rule.ts.md).

## Definitions

- `isContextLiteral` (lexical_declaration, line 11)
- `isPromptPositionName` (lexical_declaration, line 7)
- `onDeclarator` (lexical_declaration, line 27, exported)
- `SUFFIXES` (lexical_declaration, line 5)
- `{ elements }` (lexical_declaration, line 19)
- `create` (method_definition, line 26, exported)
- `{ name }` (lexical_declaration, line 31, exported)
- `handlers` (lexical_declaration, line 36, exported)

## Contained in

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

## Uses

- [core/predicates/context.fragment.predicate.ts](https://banes-lab.com/source/quality/core/predicates/context.fragment.predicate.ts.md)
- [core/selectors/context.fragment.selector.ts](https://banes-lab.com/source/quality/core/selectors/context.fragment.selector.ts.md)

## Linked from

- [core/fragment/eslint](https://banes-lab.com/anatomy/quality/folder-quality-core-fragment-eslint.md)
- [core/predicates](https://banes-lab.com/anatomy/quality/folder-quality-core-predicates.md)
- [core/selectors](https://banes-lab.com/anatomy/quality/folder-quality-core-selectors.md)

## Source

```typescript
import type { Rule } from "eslint";
import { isNode } from "#core/predicates/context.fragment.predicate";
import { stringValue } from "#core/selectors/context.fragment.selector";

const SUFFIXES = ["_PROMPT", "_SECTION", "_INSTRUCTION", "_REMINDER", "_RULE", "_GOAL", "_DISCIPLINE"];

const isPromptPositionName = function isPromptPositionName(name: string): boolean {
    return SUFFIXES.some((suffix) => name.endsWith(suffix));
};

const isContextLiteral = function isContextLiteral(init: unknown): boolean {
    if (!isNode(init)) {
        return false;
    }
    if (init.type === "TemplateLiteral" || stringValue(init) !== null) {
        return true;
    }
    if (init.type === "ArrayExpression" && Array.isArray(init["elements"])) {
        const { elements } = init;
        return elements.length > 0 && elements.every((element) => stringValue(element) !== null);
    }
    return false;
};

export default {
    create(context) {
        const onDeclarator = function onDeclarator(node: Rule.Node): void {
            if (node.type !== "VariableDeclarator" || node.id.type !== "Identifier") {
                return;
            }
            const { name } = node.id;
            if (isPromptPositionName(name) && isContextLiteral(node.init)) {
                context.report({ data: { name }, messageId: "inline", node });
            }
        };
        const handlers: [string, (node: Rule.Node) => void][] = [["VariableDeclarator", onDeclarator]];
        return Object.fromEntries(handlers);
    },

    meta: {
        docs: {
            description:
                "Disallow authoring AI-context prose as a frozen prompt-defining const — compose it as a defineContextFragment.",
        },
        messages: {
            inline: "'{{name}}' authors AI context as a frozen const. Context prose belongs in a defineContextFragment (concern + applies + params), not a monolithic literal re-sent every turn. [no_inline_context_literal]",
        },
        schema: [],
        type: "problem",
    },
} satisfies Rule.RuleModule;
```
