Date: 2026-07-09
Diagnostics are part of the language.
The canonical internal allocation authority is
src/diagnostic_catalog.rs. This document is
its checked human projection; it does not independently allocate codes or
families.
Hum is trying to make systems programming readable, safe, fast, and friendly to agents. That only works if the compiler explains problems with stable facts, not just terminal prose.
A Hum diagnostic must help five readers at once:
- a beginner who needs plain language
- a senior engineer who wants precise blame
- an IDE or LSP that needs stable structure
- a build system that needs machine-readable failure data
- an agent that needs repair instructions without guessing
Every diagnostic should answer:
What promise was broken?
Where is the smallest useful source span?
Which block is responsible?
How can a human repair it?
How can a tool recognize this class of issue next year?
Milestone 0 diagnostics contain:
code: stable diagnostic code, such asH0201title: short stable diagnostic titleseverity:errororwarningmessage: human-readable explanationspan: source file, line, and column when availablerelated_spans: optional labeled secondary source sites for a structural relationshiphelp: optional repair guidance
Terminal shape:
examples/task.hum:14:1: error[H0201]: task `save_item` saves into `tasks` without listing it in `changes:`
help: Add `tasks` under `changes:` or avoid mutating it.
JSON shape in hum check --format json and hum graph:
{
"code": "H0201",
"title": "save target not declared in changes",
"severity": "error",
"message": "task `save_item` saves into `tasks` without listing it in `changes:`",
"span": { "file": "examples/task.hum", "line": 14, "column": 3 },
"related_spans": [
{
"label": "declared task boundary",
"span": { "file": "examples/task.hum", "line": 4, "column": 1 }
}
],
"help": "Add `tasks` under `changes:` or avoid mutating it."
}related_spans is omitted when the diagnostic has no secondary blamed site.
Its labels are explanatory; the nested spans remain machine-readable source
facts. Session X app-entry diagnostics use this existing diagnostic JSON
surface for app, start declaration, and candidate task relationships.
Diagnostic JSON commands:
hum check --format json examples
hum explain H0201
hum explain H0201 --format json
hum diagnostics
hum diagnostics --format jsonhum check --format json reads source and emits source-backed diagnostics as
hum.check.v0 for editors, CI, and agents. hum explain and hum diagnostics
are offline and do not read source files. hum explain returns the stable code
title, default severity, plain-language explanation, and repair guidance for one
code. hum diagnostics returns the whole current catalog. The JSON schemas are
hum.check.v0, hum.diagnostic_explain.v0, and hum.diagnostic_catalog.v0.
JSON shape in hum check --format json:
{
"schema": "hum.check.v0",
"summary": { "files": 1, "errors": 1, "warnings": 0 },
"diagnostics": [
{
"code": "H0201",
"title": "save target not declared in changes",
"severity": "error",
"message": "task `save_item` saves into `tasks` without listing it in `changes:`",
"span": { "file": "examples/task.hum", "line": 14, "column": 3 },
"help": "Add `tasks` under `changes:` or avoid mutating it."
}
]
}JSON shape in hum explain --format json:
{
"schema": "hum.diagnostic_explain.v0",
"code": "H0201",
"title": "save target not declared in changes",
"default_severity": "error",
"explanation": "A `does:` body saves into a resource that is not listed under `changes:`, so mutation would be hidden from readers and tools.",
"repair": "Add the resource under `changes:` if the mutation is intended, or remove the save."
}JSON shape in hum diagnostics --format json:
{
"schema": "hum.diagnostic_catalog.v0",
"count": 88,
"diagnostics": [
{
"code": "H0201",
"title": "save target not declared in changes",
"default_severity": "error",
"explanation": "A `does:` body saves into a resource that is not listed under `changes:`.",
"repair": "Add the resource under `changes:` if the mutation is intended, or remove the save."
}
]
}Diagnostic codes are user-facing API.
Rules:
- Do not renumber a code after release.
- Do not reuse a removed code for a different meaning.
- If the meaning changes materially, add a new code.
- Message text may improve without changing the code.
- Help text may improve without changing the code.
- Severity may change only through an edition, feature gate, or clearly documented release policy.
Canonical inclusive family intervals:
| Inclusive interval | Status | Semantic owner | Domain |
|---|---|---|---|
H0000-H0099 |
active | source_shape |
parser and source shape |
H0100-H0199 |
active | intent_shape |
item shape and intent discipline |
H0200-H0299 |
active | declared_state_effects |
effects, mutation, and declared state changes |
H0300-H0399 |
active | cost_contracts |
cost and performance contracts |
H0400-H0499 |
active | security_trust |
security and trust boundaries |
H0500-H0599 |
active | test_evidence |
tests and regression obligations |
H0600-H0699 |
active | front_end_semantics |
checked names, types, structural app/authority, and Path boundaries |
H0700-H0799 |
active | executable_contracts |
executable contract diagnostics |
H0800-H0899 |
active | ownership_borrowing |
ownership and borrowing |
H0900-H0999 |
active | nominal_typed_failure |
explicit nominal typed failure |
H1000-H1099 |
reserved | unsafe_ffi_provenance |
unsafe, FFI, ABI, and provenance |
H1100-H1199 |
reserved | runtime_profile_policy |
runtime profile and certification policy |
H1200-H1299 |
active | target_backend_metadata |
backend, target, portability, and debug metadata |
H1300-H1399 |
reserved | concurrency_memory_ordering |
concurrency and memory ordering |
H1400-H1499 |
active | callable_effect_rows |
callable and latent-row diagnostics |
Reserved families allocate no exact code. Intervals absent from this table are unallocated rather than implicitly free.
| Code | Severity | Title | Meaning |
|---|---|---|---|
H0001 |
warning | unexpected top-level line | Source has a top-level line Hum does not understand yet. |
H0002 |
error | nested item extends past containing block | A nested item crosses its parent block boundary. |
H0003 |
error | item header missing opening brace | An item header is malformed and does not end with {. |
H0004 |
error | item block missing closing brace | An item starts but never closes with }. |
H0005 |
warning | unknown item kind | The parser found an item-like header with an unknown kind. |
H0006 |
warning | unexpected callable signature text | A task/test signature has trailing text Hum did not expect. |
H0007 |
error | callable signature missing close parenthesis | A callable parameter list starts but does not close. |
H0008 |
error | parameter missing type | A parameter lacks an explicit type. |
H0009 |
error | invalid identifier | A value name is not snake_case or a type name is not PascalCase. |
H0010 |
error | comparison chaining is not supported | One comparison uses another comparison as an operand; write and join independent comparisons instead. |
| Code | Severity | Title | Meaning |
|---|---|---|---|
H0101 |
warning | app missing why section | An app lacks a visible purpose. |
H0102 |
warning | type missing shape | A type has no fields or invariant. |
H0103 |
warning | store missing type | A store does not declare what it contains. |
H0104 |
warning | store missing purpose | A store lacks why: or expects:. |
H0105 |
error | item missing required section | A task/test lacks does:, or nontrivial behavior lacks visible why:. |
H0106 |
warning | duplicate section | The same section appears more than once in one item. |
H0107 |
warning | task missing needs section | A task with a risky boundary lacks visible preconditions. |
H0108 |
warning | section out of order | A known section appears after a later canonical section. |
H0109 |
warning | task return missing ensures section | A task returning across a nontrivial boundary lacks postconditions. |
H0110 |
warning | hollow contract line | A contract-like line is too generic, tautological, or placeholder-shaped to catch a wrong implementation. |
| Code | Severity | Title | Meaning |
|---|---|---|---|
H0201 |
error | save target not declared in changes | does: saves into a resource not listed under changes:. |
H0202 |
error | set target not declared mutable | does: sets a name that is neither locally change nor declared in changes:. |
| Code | Severity | Title | Meaning |
|---|---|---|---|
H0301 |
warning | task missing cost section | A task with loops, effects, or larger body shape lacks cost expectations. |
H0302 |
warning | cost missing check level | A cost: block lacks check:. |
H0303 |
error | compile cost missing time claim | check: compile is requested without a time: claim. |
H0304 |
error | constant cost claim has iteration | A task claims time: O(1) but visibly iterates. |
H0305 |
error | compile cost has unbounded-looking while | A compile-checked cost block contains a while without an obvious bound. |
| Code | Severity | Title | Meaning |
|---|---|---|---|
H0401 |
warning | security-sensitive task missing protects | A task touches security-sensitive resources without protects:. |
H0402 |
warning | trust boundary missing protects | A task declares trusts: without a matching safety/security promise. |
| Code | Severity | Title | Meaning |
|---|---|---|---|
H0501 |
warning | test missing covers section | A test does not say what promise it covers. |
H0502 |
warning | regression test missing regression note | A regression test does not record the bug shape. |
| Code | Severity | Title | Meaning |
|---|---|---|---|
H0601 |
error | unresolved name | hum resolve found a name that is not visible in scope. |
H0602 |
error | duplicate name in scope | Two definitions in one scope normalize to the same name. |
H0603 |
error | set target is immutable | A set target resolves to a non-mutable definition. |
H0604 |
error | read before declaration | A name is read before its later local declaration. |
H0605 |
error | unknown type name | A declaration annotation names a type that is not declared or reserved. |
H0606 |
error | return type mismatch | A trivially typed return expression does not match the task result type. |
H0610 |
error | app start missing | A top-level executable app has no starts with: section. |
H0611 |
error | app start empty | An app's starts with: section has no meaningful task name. |
H0612 |
error | app start duplicated | An app has multiple start sections or declarations. |
H0613 |
error | invalid app start name | An app start is not one bare snake_case task name. |
H0614 |
error | app start task is not a child | The named start task is not directly nested in the app; external names never satisfy it. |
H0615 |
error | multiple executable apps | Run input contains more than one top-level app. |
H0616 |
error | invalid app start result | The start task does not return Unit or Result Unit, E. |
H0617 |
error | unknown source capability | An executable app or task uses an external-capability spelling outside exact stdout.write, clock.replay, and files.read. Sandbox-bypass names are rejected as a separate authority tier. |
H0618 |
error | caller capability closure is incomplete | A caller does not declare an exact capability required by its callee's transitive direct-call closure. |
H0619 |
error | app capability maximum is incomplete | The app maximum does not cover an exact capability in the start-task closure. |
H0620 |
error | direct entry cannot carry external authority | --entry selected a task whose direct-call closure requires pinned external source authority. |
H0621 |
error | stdout operation lacks source authority | A stdout_write call lacks exact stdout.write coverage at its task or structural app boundary. |
H0622 |
error | invalid stdout_write call | The bounded output built-in does not receive exactly one checked Text argument. |
H0623 |
error | reserved built-in name redeclared | A user task attempts to redeclare the exact stdout_write built-in name. |
H0624 |
error | output-reachable recursion unsupported | A recursive call cycle can reach bounded output, so Session Z cannot assign a finite exact audit route. |
H0625 |
error | replay operation lacks source authority | A clock_replay_tick call lacks exact clock.replay coverage at its task or structural app boundary. |
H0626 |
error | invalid clock_replay_tick call | The runner-replay built-in receives an argument instead of using its exact zero-argument signature. |
H0627 |
error | reserved replay built-in name redeclared | A user task attempts to redeclare the exact clock_replay_tick built-in name. |
H0628 |
error | replay-reachable recursion unsupported | A recursive call cycle can reach replay input, so Session AA cannot assign a finite exact audit route. |
H0629 |
error | invalid opaque Path boundary | Path appears outside the one permitted structural app start parameter or in return/storage position. |
H0630 |
error | opaque Path cannot be constructed or used in source | Source attempts to construct, pass, inspect, store, return, compare, or transform runner-owned Path identity outside the exact files_read_text(path) consumption. |
H0631 |
error | file operation lacks source authority | A files_read_text call lacks exact files.read coverage at its task or structural app boundary. |
H0632 |
error | invalid files_read_text call | The hardened reader does not receive exactly one checked opaque Path argument. |
H0633 |
error | reserved file-read built-in name redeclared | A user task attempts to redeclare the exact files_read_text builtin name. |
| Code | Severity | Title | Meaning |
|---|---|---|---|
H0701 |
warning | unchecked prose contract | hum run kept a prose needs: or ensures: line visible but unchecked. |
H0702 |
error | needs contract violation | A runtime needs: predicate was false; blame belongs to the caller. |
H0703 |
error | ensures contract violation | A runtime ensures: predicate was false after success; blame belongs to the task. |
H0704 |
error | invalid executable predicate | A signaled Predicate v2 candidate is malformed, unresolved/ineligible, or ill-typed and is rejected before evaluation. |
| Code | Severity | Title | Meaning |
|---|---|---|---|
H1401 |
error | invalid or unsupported callable form | A callable-shaped type, value, or application is malformed or outside the exact Session AL envelope. |
H1402 |
error | callable signature mismatch | The resolved task value disagrees with exact task(UInt) -> UInt, failure_root = none, or the checked ordinary argument/result relationship. |
| Code | Severity | Title | Meaning |
|---|---|---|---|
H0801 |
error | use after move | A value was used after an earlier consume argument or return moved it. |
H0802 |
error | borrowed parameter written | A default-borrow parameter or one of its direct fields was targeted by set, or its field was used to acquire a writable alias; mark it change or avoid mutation. |
H0803 |
error | linear resource not consumed | A recognized linear resource reached a return, failure, or fallthrough path without exactly one visible consume action. |
H0804 |
error | linear resource consumed twice | A recognized linear resource was consumed after an earlier action already ended it on that path. |
H0805 |
error | return dependency is not a parameter | A returned-view from relationship names a non-parameter source or returns a value not visibly derived from that parameter in the V0 subset. |
H0806 |
error | iteration mutation conflict | A collection was structurally mutated with list_append while a for each loop was actively iterating it. |
H0807 |
error | stale view | A local field or element view was used after a recognized invalidating write or list growth; re-borrow after the change or copy the value before the change. |
H0808 |
error | writable alias overlap | A direct read, direct write, owner-wide access, or second writable alias may overlap an exact direct-field writable alias before its last syntactic use; use a definitely distinct field or end the alias's last use first. |
H0809 |
error | unsupported writable alias | A writable alias escapes or uses a form outside the exact local direct-field, straight-line slice; keep it local and direct or copy the field value. |
| Code | Severity | Title | Meaning |
|---|---|---|---|
H0901 |
error | fallible call requires try | A known fallible task call would propagate implicitly. |
H0902 |
error | incompatible failure propagation | Unwrapped try uses different caller and callee error roots. |
H0903 |
error | failure wrapper root mismatch | The wrapper root differs from the caller's declared error root. |
H0904 |
error | try on infallible call | try targets a task without a declared Result error root. |
H0905 |
error | direct failure root mismatch | Direct fail uses a root different from the task result root. |
H0906 |
error | unsupported try expression | A try expression is outside the two recognized direct-call forms. |
H0907 |
error | missing failure declaration | Typed failure lacks a meaningful fails when: declaration; hollow placeholders such as todo do not satisfy it. |
| Code | Severity | Title | Meaning |
|---|---|---|---|
H1201 |
error | unknown target fact record | targets: names a target record Hum does not publish. |
H1202 |
error | unknown capability family | targets: names a capability family Hum does not publish. |
H1203 |
error | unsupported target declaration | targets: contains a meaningful line with no current formal key. |
H1204 |
error | required capability unavailable on target | targets: requires a capability that a declared target marks absent or unavailable. |
H1205 |
error | conflicting target capability declaration | targets: both requires and denies the same capability family. |
H0110 is a Milestone 0 warning for obviously hollow claims in contract-like task sections such as needs:, ensures:, protects:, trusts:, watch for:, allocates:, and optimizes:.
The checker does not try to prove contracts yet. It only catches shapes that are visibly too weak to be useful, such as true, works, safe, todo, or result == result. The repair is not to add more words. The repair is to state a claim that could reject a real mistake.
Hum uses section order as pedagogy and review support. The order should read like a senior engineer thinking through the work.
Current task order:
why
uses
changes
needs
ensures
protects
trusts
fails when
watch for
cost
allocates
avoids
tradeoffs
optimizes
tests
does
Current test order:
why
uses
needs
regression
covers
avoids
cost
does
H0108 is a warning in Milestone 0. Hum should keep this as a warning until the
community has enough examples to prove the order is right.
Errors block compilation when Hum cannot trust the program meaning.
Warnings are used when the code is understandable but weakens readability, reviewability, safety, or future tooling.
A warning may become an error only when:
- the rule has proved stable
- the rule catches real defects
- the repair path is clear
humfmt,chirp, and LSP code actions can help- the change is edition-gated or clearly announced
hum lsp should map diagnostics directly:
code-> LSP diagnostic codetitle-> short hover title or code descriptionseverity-> LSP severityspan-> rangehelp-> quick fix or code action hint
The LSP must not invent codes that the compiler did not emit.
Agents should treat diagnostic codes as repair handles.
Good agent behavior:
- fix by code, not message substring
- preserve the source span unless moving code is required
- explain the promise being repaired
- add tests when the diagnostic reveals a missing promise
- avoid broad rewrites for local diagnostics
Bad agent behavior:
- scrape terminal prose when JSON is available
- silence warnings without improving the source
- add
changes:orprotects:claims that are not true - weaken
cost:just to pass a check without recording a tradeoff
Every new diagnostic code needs:
- at least one parser/checker test that emits the code
- a fixture or example when the code affects public syntax
- JSON coverage before the code is used by LSP or agents
- documentation in this file
If a diagnostic would make a beginner feel stupid, rewrite it.
If a diagnostic would make a senior engineer ask "but where is the real blame?", rewrite it.
If an agent cannot repair from the code, span, message, and help, enrich the machine form before adding clever syntax elsewhere.