control: log every route.open refusal and count them by daemon code (closes #94) - #96
Conversation
CONSUMER-IMPACT: none — log event + counter, no wire change
CONSUMER-IMPACT: none — counter key set is daemon vocabulary; no wire change
There was a problem hiding this comment.
All reported issues were addressed across 3 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
|
Read at 24adb39. Both pins landed as hard constraints and the CI: the ubuntu red on your head is #93 (pre-existing; fix under two-arm test on a VM now), not this PR — windows is still running. I'll merge once windows is green and the |
CONSUMER-IMPACT: none — log field escaping only
CONSUMER-IMPACT: none — log field formatting only
|
Event proven escaped in One consequence of Debug worth a line in the docs when this ships: normal ids now log quoted — Gates: fmt, clippy |
|
Your head 989a1b6 went red on windows too — that one is also not yours: |
|
Merged at 3582e6f from your head 989a1b6 (my gate: fmt, clippy native + windows-gnu, |
Closes #94. Both pins from the ruling, plus one hardening the cross-family review forced.
What
Event. Every path in
handle_route_openthat refuses the open now goes through one helper (route_open_refusal_frame→observe_route_open_refusal), which emitswith
connection_id= the requester. The supervised-but-absent branch addsstate,enabled,liveas separate tracing fields (state = %status.state, not prose), so a consumer's own log can be joined on them. 17 refusal returns route through the helper;invalid_project_rootis left out deliberately — it rejects malformed input, it does not refuse an open.Counter.
route_open_refused_by_codeinobservability.rs, snapshotted into the existingserver.describecountersobject and rendered byck daemonbesidemodule_frames_dropped_no_route_by_module(summary line only when non-empty; verbose lists the map). Nosubc-controltype changed; goldens byte-identical.Counter keys are daemon vocabulary, never a module-chosen string. The relay-rejection site forwards the module's
body.codeon the wire as before, but counts under the fixed keymodule_rejectedand carries the raw code on the event asmodule_code. The increment signature is&'static strwith adebug_assert!against the closedROUTE_OPEN_REFUSAL_COUNTER_CODESset. This is what the review caught: with the raw code as key, a module could grow the map for the daemon's lifetime and push\x1b]52;…throughck daemonto an operator's terminal — the same class the provenance renderers already escape. Bothck daemonrenderers additionally go throughterminal_safe_string/terminal_safe_json.Tests (mutation-proved, each direction)
route_open_supervised_absence_emits_refusal_fields_and_counts_code— drives the supervised-absent branch, asserts the event's fields and the counter delta in one test. Severinginfo!→.expect("route.open refusal event")panics; severing the increment →left: Null, right: {"module_warming": 1}.route_open_module_rejection_uses_daemon_counter_key— relay rejection carrying"\x1b]52;c;AAAA\x07"lands as{"module_rejected": 1}and the raw string is asserted absent. Substituting&body.codeas the key →left: {"\u{1b}]52;c;AAAA\u{7}": 1}.route_open_refusal_counter_renderers_escape_terminal_controls— both renderers, hostile key, no byte< 0x20in output.Gates on
9c718c6b+ these two commits:cargo fmt --check,cargo clippy --workspace --all-targets -- -D warnings,cargo test -p subc-core842 passed / 0 failed / 1 ignored. Workspace run shows only the #93 failure.CONSUMER-IMPACT: noneon both commits — log event + counter, no wire change.Why now
Sunday's insula#14 exercise: the daemon's refusal code was the one fact neither end of the wire could attest, so the verdict rested on a state-machine argument with a stated residual. With this line, the daemon says which code it sent.
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.Summary by cubic
Previously,
route.openrefusals were not consistently observable. Now every refusal emits an INFO event and increments a daemon counter, giving operators the refusal code without changing the wire response (closes #94).connection_id; untrustedmodule_idandmodule_codefields useDebugformatting so terminal control characters stay out of logs. Supervised-but-absent refusals also includestate,enabled, andlive.route_open_refused_by_codethroughserver.describeand renders it inck daemonbeside frame-drop statistics.module_code, but count undermodule_rejected. Terminal renderers escape hostile values.Written for commit 989a1b6. Summary will update on new commits.