1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
//! Non-fatal `HARN-SRV-*` diagnostics gathered while reading export attributes.
/// A `HARN-SRV-*` diagnostic raised while building the export catalog.
///
/// These flag the malformed `@route(...)` / `@scopes(...)` attribute
/// forms that the collector would otherwise drop silently — leaving a
/// handler mis-routed, unmounted, or less scope-restricted than the
/// author intended. They are surfaced by the serve adapters at startup
/// (see [`emit_export_diagnostics`]) rather than aborting catalog
/// construction, so one bad attribute doesn't take down a script whose
/// other handlers are fine.
/// `@route` carries an argument that is not a string literal, so the
/// method/path positions are ambiguous and the handler is not mounted.
pub const ROUTE_ARG_NOT_STRING: &str = "HARN-SRV-001";
/// `@route` has the wrong number of arguments — it takes a path, or a
/// method and a path. The handler is not mounted.
pub const ROUTE_BAD_ARITY: &str = "HARN-SRV-002";
/// `@scopes` carries an argument that is not a string literal; that
/// scope requirement is dropped, leaving the route less restricted.
pub const SCOPES_ARG_NOT_STRING: &str = "HARN-SRV-003";
/// `@job` carries a non-string name, or more than one positional
/// argument. The function is not registered as a job.
pub const JOB_BAD_NAME: &str = "HARN-SRV-004";
/// `@schedule` is malformed — it takes a cron expression and an optional
/// timezone, both string literals. The schedule is dropped.
pub const SCHEDULE_BAD_ARGS: &str = "HARN-SRV-005";
/// `@queue` carries a non-string queue name, or the wrong number of
/// arguments. The queue binding is dropped.
pub const QUEUE_BAD_NAME: &str = "HARN-SRV-006";
/// `@retry(max:, backoff:)` carries an unrecognised argument shape — a
/// positional argument, non-integer `max`, or an unknown `backoff`
/// keyword. The offending field is dropped (the rest of the policy still
/// applies).
pub const RETRY_BAD_ARGS: &str = "HARN-SRV-007";
/// `@schedule` / `@queue` / `@retry` appears without a `@job` attribute.
/// Those modifiers only mean something on a job, so they are ignored.
pub const JOB_MODIFIER_WITHOUT_JOB: &str = "HARN-SRV-008";
/// `@stream` carries arguments — it is a bare marker. The marker is
/// dropped, so the route dispatches into the VM like any other handler.
pub const STREAM_BAD_ARGS: &str = "HARN-SRV-009";
/// `@stream` appears on a declaration without an HTTP route (no
/// `@route(...)`, no `handler_*` convention, or a pipeline). Streaming
/// only means something on a routed `pub fn`, so it is ignored.
pub const STREAM_WITHOUT_ROUTE: &str = "HARN-SRV-010";
/// `@raw` carries arguments — it is a bare marker. The marker is
/// dropped, so the route dispatches into the VM like any other handler.
pub const RAW_BAD_ARGS: &str = "HARN-SRV-011";
/// `@raw` appears on a declaration without an HTTP route. Raw-body
/// hand-off only means something on a routed `pub fn`, so it is ignored.
pub const RAW_WITHOUT_ROUTE: &str = "HARN-SRV-012";
/// `@raw` and `@stream` appear on the same declaration. They contradict
/// on body handling (`@stream` never reads the request body, `@raw`
/// buffers it for the provider), so `@raw` is dropped and the route
/// behaves as `@stream`.
pub const RAW_CONFLICTS_WITH_STREAM: &str = "HARN-SRV-013";
/// `@ws` carries arguments — it is a bare marker. The marker is dropped,
/// so the route dispatches into the VM like any other handler.
pub const WS_BAD_ARGS: &str = "HARN-SRV-014";
/// `@ws` appears on a declaration without an HTTP route. A WebSocket
/// upgrade only means something on a routed `pub fn`, so it is ignored.
pub const WS_WITHOUT_ROUTE: &str = "HARN-SRV-015";
/// `@ws` and `@raw` appear on the same declaration. A WebSocket
/// handshake carries no request body, but `@raw` exists to buffer one, so
/// they contradict; `@ws` is dropped and the route behaves as `@raw`.
/// (`@ws` + `@stream` is *not* a conflict — it is the combined route that
/// upgrades a genuine handshake and falls through to the stream otherwise.)
pub const WS_CONFLICTS_WITH_STREAM_OR_RAW: &str = "HARN-SRV-016";
/// `@policy(...)` carries an argument that is not the supported
/// `kinds: "..."` string form (an unknown key, a positional argument, or a
/// non-string value). The offending argument is dropped, leaving the
/// route's principal-kind guard incomplete; any host-side defense-in-depth
/// check still applies.
pub const POLICY_BAD_ARGS: &str = "HARN-SRV-017";
/// `@annotations(...)` carries something other than named boolean arguments, or
/// names a hint MCP does not define. The offending hint is dropped; the rest of
/// the declaration still applies.
pub const ANNOTATIONS_BAD_ARGS: &str = "HARN-SRV-018";
/// Print catalog diagnostics to stderr at server startup, matching the
/// `[harn] …` banner the adapters already emit. Standalone serve
/// commands call this so authors see malformed attributes immediately;
/// embedders that build a router directly can read
/// [`super::ExportCatalog::diagnostics`] and render them in their own UI.