Repository navigation
Open
Labels
app/idPackage/app: id (pkgs/ or apps/ in this repo)Package/app: id (pkgs/ or apps/ in this repo)effort/sSmall: expected under 2 hours of workSmall: expected under 2 hours of workkind/enhancementpriority/lowNice to have; do when convenientNice to have; do when convenientqueue/claimedQueue worker lifecycle stateQueue worker lifecycle statesource/queue-workerFiled or worked by the queue/worker pilotFiled or worked by the queue/worker pilotstatus/in-progressQueue worker lifecycle stateQueue worker lifecycle statetask/fixhas a fix task queuedhas a fix task queueduser/reviewNeeds a user-look: Muse reviews first and handles what it canNeeds a user-look: Muse reviews first and handles what it canwork/assignedQueue worker lifecycle stateQueue worker lifecycle state
Description
Residual gap found while triaging #2244 at main 1e3763f (both phases shipped: #3891 core, #3960 integration).
Problem
#2244's "Done when" requires that "the counters are visible" so an operator can tune the limits they can see. Today the per-(local node, remote endpoint) frame/byte counters exist and are correct, but their only reader is Rust code:
WorldProtocol::abuse_counters()(pkgs/id/src/world_net.rs:156) returnsVec<((NodeId, EndpointId), Counters)>.- It has no other caller in the tree (
git grep abuse_counters -- pkgs/id/src), no CLI verb prints it, and no metrics/status endpoint exposes it.
So an operator running id cannot see any counter value, which means the tuning half of the issue is not reachable without writing code.
Work
- Pick the surface the design allows (metrics or
id peers): add a counter section/flag toid peers(pkgs/id/src/commands/peers.rs) backed by anabuse_counters()snapshot from the live protocol, or expose the same snapshot through the existing metrics/status route used for world state. - Include both directions (inbound/outbound frames and bytes), the endpoint id in the same rendering
id peersalready uses, and the policy values (rate/burst) alongside so a value can be judged relative to its bucket. - Keep it read-only and bounded: snapshot per invocation, no unbounded state retention; reuse
CounterRegistry::pruneretention semantics rather than adding a second lifetime. - Test: a snapshot with two endpoints renders both rows deterministically, and the output stays stable when counters are empty.
Related: #2244 (closed by this triage), #3881, #3882, #2033 (design, doc/2026-11-01_design_id2033.md), #2247 (budgets consume the same counters).
Metadata
Metadata
Assignees
Labels
app/idPackage/app: id (pkgs/ or apps/ in this repo)Package/app: id (pkgs/ or apps/ in this repo)effort/sSmall: expected under 2 hours of workSmall: expected under 2 hours of workkind/enhancementpriority/lowNice to have; do when convenientNice to have; do when convenientqueue/claimedQueue worker lifecycle stateQueue worker lifecycle statesource/queue-workerFiled or worked by the queue/worker pilotFiled or worked by the queue/worker pilotstatus/in-progressQueue worker lifecycle stateQueue worker lifecycle statetask/fixhas a fix task queuedhas a fix task queueduser/reviewNeeds a user-look: Muse reviews first and handles what it canNeeds a user-look: Muse reviews first and handles what it canwork/assignedQueue worker lifecycle stateQueue worker lifecycle state
Activity
dezren39 commentedon Nov 3, 2026
🤖 Agent note · handed off
opencodeid peers) #4918) to its terminal state under this queue's worker id. Claim labels work/assigned, queue/claimed, status/in-progress applied by the handing-off worker.id peers) #4918dezren39 commentedon Nov 3, 2026
Implementation brief — 2026-11-03 (repo-health queue,
repo-worker-code)Triage at
ffad69add. The gap is exactly as described:WorldProtocol::abuse_counters()(pkgs/id/src/world_net.rs:181) has no non-test caller,pkgs/id/src/commands/peers.rsrenders no counters, and no web route exposes them.One acceptance detail needs a decision first
The issue asks for both directions. The shipped registry does not record them separately:
CounterRegistry::record(pkgs/id/src/abuse.rs:564) aggregates oneCounters { frames, bytes }per(local_node, remote_endpoint)and ignores theDirectionthe charging path already carries (frames::charge_frame_budgeted→check_frame_and_bytes_budgeted, bothDirection::InboundandDirection::Outboundland in the same row). So "render inbound and outbound" is either:CounterEntryholdsinbound/outboundCounters;recordtakes theDirectionits callers already have;snapshotreturns both plus the total. Call sites:pkgs/id/src/frames.rs:182,pkgs/id/src/world_net.rs:421/464. ExistingCountersconsumers keep the aggregate. ~1 file + 3 call sites + tests.Surface and plumbing (the expensive half)
id peersis the cheaper surface to document but not to feed: the CLI talks to a serve overMETA_ALPN, andMetaProtocol::new(pkgs/id/src/protocol.rs, constructed atpkgs/id/src/local.rs:194and inserve.rs) has no handle to the world abuse evaluator. Either surface needs one handle threaded:serve.rsbuildsWorldProtocol::new(hub.clone())inline inside the router builder (pkgs/id/src/commands/serve.rs:1191). Hoist it to alet world_protocol = ..., keep a clone, and eitherArc<Mutex<AbuseEvaluator>>(or a smallAbuseSnapshotclosure) intoMetaProtocoland answer a newMetaRequest::AbuseCounters→MetaResponse::{rows, policy}from theid peers --abusepath (pkgs/id/src/commands/peers.rs:255already does theListPeersround-trip), orGET /api/abusenext to/api/peersinpkgs/id/src/web/routes.rs:333with the same handle in web state.AbuseEvaluator::policy()is not exposed today; add apub fn policy(&self) -> AbusePolicy(or returnBucketLimitsfor the authorized bucket) so the rendering can show rate/burst next to each row.EndpointIdformatting already used byid peers; sort rows (registrysnapshotalready sorts by(NodeId, EndpointId)); keep it a per-invocation snapshot (no new state), and reuseABUSE_COUNTER_RETENTION_MSprune semantics rather than adding a second lifetime.Tests
cargo test -p idtargeted: (a) two-endpoint snapshot renders both rows deterministically, (b) empty snapshot renders the empty section and exits 0, (c) direction split (if option 1) charges inbound and outbound independently. Note-p idcompiles the whole crate — expect several minutes; CI covers the rest.Queue state
Parked for continuation (worker
repo-worker-code, lane9aca43b4-5439-4939-9f71-323f5d32521b) because the run budget ended during the investigation pass; no branch created, no code changed.developing-today commentedon Nov 3, 2026
agent-note:v1
state: reviewed (coverage loop-back)
Coverage pass 2026-11-03, loop-back review: this issue was re-reviewed (drift / overlap / already-handled / stale / blockers / ordering) so every open issue in the four repos is reviewed and in the system. Verdict: still live; in the system as task 8033 (small_fix, claimed, priority 30) in repo-health-code-pilot. Labels audited and synced. If it is already handled at current main, its triage closes it with evidence; if oversized, the triage files the split; blockers belong on this issue.
Found via: coverage loop-back 2026-11-03
fix(id): surface per-peer frame/byte abuse counters with direction sp…
dezren39 commentedon Nov 3, 2026
🤖 Agent note · handed off
id peers) #4918dezren39 commentedon Nov 3, 2026
🤖 Agent note · handed off
fix(id): pass abuse handle at remaining MetaProtocol::new test sites (#…
dezren39 commentedon Nov 3, 2026
🤖 Agent note · handed off (re-handoff, resume state preserved)
id peers) #4918 (surface per-peer frame/byte counters) — execution lane assigned to opencode; handed off to the laptop claimant (opencode-claimant). Prior session's work is preserved: PR fix(id): surface per-peer frame/byte abuse counters with direction split (#4918) #5096 is OPEN and mergeable on branch queue/8033-4918-abuse-counters; resume = revalidate PR fix(id): surface per-peer frame/byte abuse counters with direction split (#4918) #5096 checks (basic production-line-guard runner was still queued at last check) and merge when green.id peers) #4918) once checks are green.id peers) #4918 · PR fix(id): surface per-peer frame/byte abuse counters with direction split (#4918) #5096dezren39 commentedon Nov 4, 2026
🤖 Agent note · escalated
This item carries queue/claimed + work/assigned + status/in-progress, but nothing has moved in ~13h against a 2h (effort/s) expectation. Adding user/review per the lifecycle protocol §6 escalation rule. Note: the repo-queue Supabase backend is in an outage window today (code#5370), so the monitor is NOT requeueing from GitHub alone this run — if the holding session is done, the next monitor run after DB recovery will reset the labels and requeue; if you are still holding this, please checkpoint now and the escalation clears.