docs: update configuration and diagnostics

This commit is contained in:
Onur Özkan committed 2026-08-23 00:40:50 +03:00
1 parent fdf82a5114
commit 21e9497915
8 files changed
+157 -123

No files matched your search

+65 -28
View File
@@ -3,49 +3,86 @@
Public Kaptan error enums derive the pure `KaptanError` implementation:
```rust
#[derive(Debug, kaptan_log::KaptanError)]
#[derive(Debug, kaptan_err_propagate::KaptanError)]
enum SensorError {
#[kaptan_error(id = 12345)]
TransferFault,
#[kaptan_error(id = 12346)]
UnexpectedIdentity(u8),
}
#[kaptan_err_propagate::propagate]
fn service_sensor() -> Result<(), SensorError> {
read_sensor()?;
Ok(())
}
```
The derive implements `core::error::Error`, `Display`, and `ErrorReport`. It
creates a static `module::Type::Variant` error path without allocating,
publishing telemetry, exposing generic source values, or changing safety
state. Renaming a module, type, or variant changes that path; it is not a
stable machine protocol identity.
requires a nonzero explicit ID on every variant and retains no type, variant,
or module string. `Display` renders the decimal ID. Renaming, moving, or
reordering a Rust variant therefore does not change its receiver contract.
Missing and same-enum duplicate IDs are rejected by the derive. Reusing an ID
across error enums generates the same reserved linker symbol and fails the
final firmware build.
Normal-task code may use `log::error!("{error}")`; it is routed as a bounded
`KAPTAN_ERROR`. ISR-adjacent flight paths may enqueue the derived static
message through their existing bounded mailbox. Neither route is a replacement
for safety state, actuator inhibit, or typed configuration results.
`#[kaptan_err_propagate::propagate]` observes the ordinary `Result` produced
by one terminal diagnostic boundary. If an `Err` leaves that function, the attribute
makes one nonblocking admission attempt and returns the exact same `Err` to the
caller. The record contains the final converted error ID and the compile-time
`file:line` of that annotated boundary. This is where the `Err` enters
diagnostics, not necessarily the line where a deeper callee originally
constructed it. `?`, explicit returns, result aliases, and `From` conversion
retain their normal Rust behavior. An error handled inside the function is
silent.
## Stable IDs
Production error IDs are plain decimal numbers from `1` through `59999`.
Values from `60000` through `65535` are reserved for tests, and `0` is
invalid. Once issued, an ID is never renumbered or reused, even if its error
variant is removed. Adding a variant therefore requires allocating a new ID;
renaming, moving, or reordering an existing variant keeps its assigned ID.
The example numbers above are illustrative and must be replaced with
unallocated catalog values when used in production code.
Only the terminal boundary is annotated. If nested functions are both
annotated, each boundary makes its own report attempt; the ingress does not
mark or mutate error values to deduplicate them. Expected validation,
backpressure, retry, and untrusted-input results remain unannotated. In
particular, transient SPI/I²C `Busy` and unavailable range measurements stay
inside their service retry/idle paths. In contrast, every logging
macro—including `kaptan_log::error!`—produces only
`KAPTAN_LOG`. Error propagation is not a replacement for safety state,
actuator inhibit, or typed configuration results.
`kaptan-err-propagate` owns error identity and its independent one-slot
ingress. A pending record contains only the compact ID and a static reference
to the propagation boundary's `file:line`. The MAVLink adapter copies that
location into its fixed field when constructing `KAPTAN_ERROR`. Producers never
encode or transmit MAVLink themselves. Admission is bounded and lossy if a
different typed error is already pending.
## What the receiver sees
- Configuration writes receive authoritative structured failures through
`KAPTAN_CONFIG_RESULT`: operation, lifecycle state, field IDs, validation
rule, and protocol error code.
- Runtime driver and link faults reach the F722 MAVLink worker as a
`KAPTAN_ERROR` path, subject to bounded transport admission. The error
payload is `{ level, flags, path_length, additional_information_length,
path[96], additional_information[64] }`; `level` preserves the originating
MAVLink-compatible severity from Emergency through Error, each length
identifies the valid UTF-8 prefix, and the optional information field may be
empty. A `KaptanError` derive supplies the type/variant path and normally
leaves additional information empty. `log::error!` uses the Rust log target
as the path and the formatted message as additional information.
- A rejected configuration operation may enqueue a companion `KAPTAN_ERROR`
whose path is the high-level `ProtocolError` identity. It is intentionally
not correlated and carries no field/rule detail; the matching
`KAPTAN_CONFIG_RESULT` remains the sole precise authority.
rule, and protocol error code. A terminal persistence failure also reports
the storage-only `CommitTransactionError::Store` boundary once as
`KAPTAN_ERROR`; replaying the cached command result does not repeat the error
or the flash operation.
- Terminal typed `ErrorReport` faults reach the F722 MAVLink worker as a
`KAPTAN_ERROR`, subject to bounded transport admission. The payload is
`{ error_id, raised_at[96] }`. `raised_at` is a zero-padded UTF-8
`file:line` prefix for the annotated propagation boundary.
The message kind itself identifies an error; no level is duplicated in the
payload. Dynamic human-readable context belongs in `KAPTAN_LOG`, while
structured protocol failures remain in their owning response message.
- Control, navigation, safety, and simulator error types are derive-ready but
their live owners are not yet attached to a MAVLink worker.
- `KAPTAN_SHUTDOWN`, defined in `definitions/kaptan/shutdown.xml`, represents
only a future completed orderly,
output-inhibited shutdown. It is not a shutdown request, panic, hard-fault,
reset, or retention-record protocol. F722 still uses `panic-halt`; it does
not claim a live panic frame or retained-record replay.
F722 still uses `panic-halt`; it does not claim a live panic frame or
retained-record replay.
No diagnostic message may synchronously transmit from a panic handler, hard
fault, ISR, DMA callback, or motor-inhibit path. A later target integration