Index Lint
Configure, fix, and suppress Crux's authored-graph lint findings.
Index Lint is the Project Health checklist for authored AI systems. It is not a TypeScript style linter. It looks for design issues that matter to prompts, agents, tools, flows, routing, memory, workspaces, and eval coverage.
For CI, run crux check. It compiles Catalog Health without a daemon and
defaults to gating error findings. crux lint uses the same one-shot compiler
and finding selection but keeps its compatibility default of no gate.
crux check --profile recommended
crux check --profile strict --fail-on warning --json
crux lint # inspect without gating by defaultUse it when Devtools or the TUI shows findings such as:
- a tool or prompt is missing an inspectable schema
- an agent handoff points at something Crux cannot see
- a router target is unresolved
- a runnable definition has no visible eval coverage
- a workspace write has no visible guardrail or policy
- a media operation discards its result or declares a provably unsupported adapter
- a retained media option could expose raw payloads, locators, or provider identifiers
Start With Recommended
Most projects should use the recommended profile:
// crux.config.ts
import { config } from "@use-crux/core";
export default config({
lint: {
profile: "recommended",
},
});Profiles are additive:
| Profile | Use it when |
|---|---|
recommended | You want high-signal findings during normal development. |
strict | You want stronger production-readiness checks. |
experimental | You want early feedback from rules that are still being proven. |
off | You need to disable index lint findings for a project. |
What the rules cover:
- inspectable input/output schemas and hidden required prompt input
- dynamic injection visibility
- flow replay and suspend contracts
- routing defaults and runtime target identity
- unresolved RAG recipe steps and runtime serialization safety
- media operations: discarded results, unsupported adapter/operation pairs, unsafe retained options, and invalid edit, transcription, or speech configurations (deterministic source checks that never inspect media bodies)
Stable-beta rules are the default quality-gate set; treat preview rules as advisory until they are promoted. Stability tiers, the promotion policy, and the media-rule scope live in the Index Lint reference.
Read Findings As Design Feedback
Each finding should tell you what happened, why it matters, and what to do next. The important fields are:
ruleId: the stable rule identifierseverity:info,warning, orerrormessage: what Crux foundrationale: why the rule existsevidence: source or graph evidence behind the findingfixes: suggested code, config, docs, or suppression actionsdocsUrl: the rule reference page
In Devtools, start with the message, evidence, and suggested fixes. The reference fields are useful when you are building tooling, but most users do not need to inspect raw JSON.
Fix Before Suppressing
Prefer fixing the authored system:
- export definitions that should be visible to Devtools
- add stable ids to prompts, agents, tools, routing primitives, and compositions
- add inspectable input/output schemas where the model or tooling needs structure
- add eval or quality coverage for runnable definitions
- add guardrails or explicit policy around workspace and blackboard writes
Suppress a finding only when the exception is intentional and the reason will still make sense to someone else later.
// crux-lint-disable-next-line tool.missing_input_schema -- generated adapter validates externally
export const generatedTool = tool({
id: "generated",
execute: async () => "ok",
});File-level suppressions should be rare:
/* crux-lint-disable-file definition.missing_eval_coverage -- temporary prototype */Unknown rule ids and unused suppressions are reported as index diagnostics so stale comments do not silently accumulate.
A matched suppression does not delete the finding. Crux retains it in the
Project Index with the directive location, exact line, next-line, or file
scope, and the optional authored reason. This makes a cached snapshot
self-describing even if the source later changes or is unavailable.
In Devtools, Index Health and each Catalog definition keep those retained
rows available for audit. Active and suppressed totals are shown separately;
severity, rule, affected-definition, badge, and default Health verdicts count
active findings only. A suppressed-only project therefore reports 0 active
and its suppressed total instead of claiming that no findings exist.
Every retained row is explicitly tagged suppressed. Its expanded evidence labels the finding source separately from the suppressing directive source and shows the directive scope and location. Reasons are optional: a directive with no reason still shows its suppression state and evidence as no reason recorded.
Default crux lint, crux check, and TUI views hide suppressed findings. Use
--include-suppressed when you want to audit the retained rows. Displaying a
suppressed row never makes it participate in a --fail-on gate; gates always
consider active findings only.
Run Detail can also show these rows under Current project health when the run recorded matching definition references. That card is a read-time view of the currently materialized Project Index—not proof of which findings or directives existed when the run executed. It separates active and suppressed rows, does not change the run status or any lint/check gate, and links each matched definition back to Catalog.
Tune A Rule
Use per-rule config when a project needs a different severity or when a rule is not relevant yet:
// crux.config.ts
import { config } from "@use-crux/core";
export default config({
lint: {
profile: "strict",
rules: {
"definition.missing_eval_coverage": { severity: "info" },
"prompt.missing_output_schema": { enabled: false },
},
},
});Keep rule overrides narrow. If many rules need disabling, the project may be missing visibility, eval coverage, stable authored ids, or schemas that Devtools can inspect.
When A Finding Looks Wrong
First check whether Crux can fully see the project:
- Fix parse or import diagnostics.
- Make sure the relevant definition is exported from normal TypeScript source with a stable id when needed.
- Run
crux check --fail-on noneto reproduce through the complete one-shot pipeline. - If comparing with Devtools, use
crux lint --serverexplicitly and confirm the same profile/suppression settings. - Re-run indexing after config changes.
If Crux can see the project and the finding is still wrong, suppress it with a reason and open a rule issue with the finding evidence.
Related
- Reference: Index Lint
- Reference: Index Lints
- Reference: Project Index
- Guide: Catalog runtime evidence
- Guide: Runs and delivery health
- Advanced: Writing an Indexer Extension