nichlink-run-method
简体中文 | English
nichlink-run-method is the run_method execution surface of NichLink: runtime
state instances plus trace bindings. The protocol itself — the Registry
tree, transactions, graft validation, plugin policy, and parsers — lives in
the kernel (nichlink-core); this crate binds it to the process lifetime.
What stays here:
CallTraceframe stacks, locals, and data edges (trace_mode_from_envreadsNICH_LINK_TRACE; the enum and its parser are kernel types)- Declaration macros:
host!,application!,static_graft_plan!,graft_plan!,trace_call!, and the generated*_object!family - The ungated graft-record loader and overlay entry:
apply_recorded_grafts,load_graft_records,load_graft_record,graft_record_root,LoadedGraft,GraftOverlay, and the re-exportedRecordReport/RecordedGraft/ResolvedRecord. It is deliberately outsideauthoring, so a host reads.nichlink/external-grafts/without pulling insyn; the precedence policy and reports are indocs/graft.md.apply_recorded_graftsprints onewarning:/note:line per report to stderr before returning, so a record that is skipped (a graft that silently never happens) cannot go unnoticed; the same items stay inGraftOverlayfor a host that routes evidence into its own log. A plan that cannot be parsed, a directory that disagrees with its plan'sgraft, and a contradictory identity-vs-path record areErrinstead: none of them has a legitimate reading. - The authoring executor (feature
authoring): applies file plans to the host'ssrc/tree. The pure plan/render logic and theFACEfield dictionary live in the kernelauthoringmodule call_reportrendering over a live trace
A host crate depends on this crate and calls nichlink_run_method::host!();
once at the crate root; the build-time half is nichlink-build-method.
Runtime checks
runtime_checks: [...] on a face is a host API, not an automatic hook: the
kernel never observes a value, so the host owns the boundary. Build the
RuntimeValue and call Registry::health_check with the face's NodeId where
the value crosses into a plugin or consumer. Pass Vec::new() as call_path
when no trace is active (CallTrace::current_path() when one is). On failure the
error aggregates one child per failed check. Five readers expose the facts the
constructor was given (core/src/registry_core/diagnostic/error.rs):
| Reader | Returns | Population |
|---|---|---|
node() |
The NodeId of the face the failure is about |
always set |
path() |
The logical registration path the failure was reported at | always set; a phase with no live path writes a placeholder instead |
source() |
&DiagnosticSource, the declaration source the failure points back to |
always set; a phase with no declaration to point at synthesizes a <…> location at line 0, column 0 |
message() |
The human-readable failure message | always set |
children() |
The aggregated child failures, one per failed sub-check | empty unless the phase aggregated sub-failures |
Placeholder paths are <unknown:{node}>
(core/src/registry_core/tree/inspection/inspection.rs:74),
<missing-parent:…>/…
(core/src/registry_core/tree/transaction/transaction.rs:167,
core/src/registry_core/tree/graft_ops/graft_ops.rs:146), and <edited>/…
(core/src/registry_core/tree/graft_ops/graft_ops.rs:186); synthesized sources
are <runtime> (inspection.rs:75), <registry-connector>
(core/src/registry_core/tree/connector/connector.rs:205),
<owned-snapshot-batch>
(core/src/registry_core/tree/transaction/transaction.rs:83), <migration>
(core/src/registry_core/tree/graft_ops/graft_ops.rs:54), and <graft>
(core/src/registry_core/tree/graft_ops/graft_ops.rs:294,
core/src/registry_core/tree/graft_ops/reconcile.rs:166).
Two rules for reading a health_check failure:
- The top-level
message()is the fixed aggregate sentenceruntime health check failed(core/src/registry_core/tree/inspection/inspection.rs:110); it does not name the failing check. Other aggregating phases keep the same shape:registration connector rejected (N face(s))(core/src/registry_core/tree/connector/connector.rs:211) andsnapshot batch rejected (N error(s))(core/src/registry_core/tree/transaction/transaction.rs:89). - The failing check's own name and text are in
children()[0].message(), built ascheck `<name>`: <message>(inspection.rs:95).Displayrenders the aggregate plus every child, which is whyeprintln!("{error}")in the example below prints both.
use ;
A runnable version lives at
examples/control-button/examples/health_check.rs:
cargo run -p nichlink-example-control-button --example health_check.