fix(ui): give four app-panel form controls a programmatic accessible name - #7594
Conversation
…name Four controls across the owner/playground/maintainer-settings/digest panels had no programmatic label — a sibling (non-associated) <label> or none at all — so a screen reader got no accessible name (WCAG 3.3.2/4.1.2). Fixed with association attributes only, zero visual diff (no layout/style/text/nesting change), so this stays in the no-visual-change lane (JSONbored#7532): - owner-panel.tsx: `htmlFor="owner-repo"` on the Repository label + matching `id` on the Input. - playground-panel.tsx: `htmlFor`/`id` pairs for the Tool select, Repo input, and Branch input. - maintainer-settings.tsx (FocusManifestEditor): `aria-label="Focus manifest editor"` on the JSON textarea. - digest-panel.tsx (SubscribeForm): `aria-label="Digest notification email"` on the email input. Adds a regression test per file (none existed) asserting each fixed control is reachable by its accessible name via Testing Library's getByLabelText / getByRole({ name }). Closes JSONbored#7532
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
|
Tip ✅ LoopOver review result - approve/merge recommendedReview updated: 2026-07-21 00:32:38 UTC
Review summary Nits — 4 non-blocking
Decision drivers
Context & advisory signals — never blocks the verdict
Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://loopover.ai/docs/loopover-commands 🧪 Experimental — new and may change. Visual preview
Click any thumbnail to open the full-size screenshot. Before = production · After = this PR's preview deploy. Scroll preview
A short scroll-through clip (desktop) — click either thumbnail to open the full animation. Evidence for scroll-linked behavior a single screenshot can't show. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.
|
…as secret leaks (#7994) * fix(review): stop bare hotkey/coldkey mentions from false-positiving as secret leaks containsSecretLikeText matched the bare words "hotkey"/"coldkey" anywhere in a registry document, unlike "wallet" (already scoped to "wallet path"). A Bittensor hotkey is the standard PUBLIC miner identifier, not secret material, and appears routinely in ordinary registry content -- API paths, field names, even notes explicitly denying any such data ("No wallet/hotkey data"). Confirmed root cause of 4 mis-closed metagraphed PRs in one day (#7469, #7589, #7591, #7594). Scope hot/coldkey the same way wallet already is: require adjacency to something that actually indicates key material (a keystore path, a private-key/password/ mnemonic/seed qualifier) rather than a bare word match. Also fixes a companion bug: the privacy scrub that redacts private-rubric terms from dynamically assembled/AI-generated public text was being applied to the reviewer's own static, hardcoded secret-detection message too, rendering "...secret, wallet, PAT..." as the confusing "...secret, [context], PAT...". AdvisoryFinding gains an alreadyPublicSafe flag a producer can set when its detail/publicText has no interpolated contributor or AI content, so a fixed message an engineer already wrote and reviewed renders verbatim. Closes #7981 * fix(engine): bump loopover-engine patch version for gate-decision twin parity The #7981 fix touched src/rules/advisory.ts (formatCheckRunOutput) without a matching edit to its gate-decision twin (packages/loopover-engine/src/advisory/gate-advisory.ts), which has no such function. check-engine-parity.ts requires a version bump in that case; expected-engine.version must stay in sync with it too. * fix(scripts): resolve baseEngineVersion via git by default in engine-parity check runEngineParityChecks aliased an un-overridden baseEngineVersion straight to headEngineVersion, while its changedFiles default already resolved via a real git diff against origin/main. That asymmetry meant a genuine version bump could never be detected unless the caller passed baseEngineVersion explicitly (only runEngineParityMain did), so any branch with a single-sided gate-decision edit plus a correct version bump still failed this check. Discovered while landing the #7981 hotkey/coldkey fix, which needed exactly that bump for src/rules/advisory.ts's formatCheckRunOutput. * fix(release): sync release-please manifest with the engine version bump .release-please-manifest.json tracks packages/loopover-engine's version independently of package.json; the 3.4.0 -> 3.4.1 twin-pair parity bump needed a matching entry here too, caught by release-manifest:sync:check. --------- Co-authored-by: loopover-orb[bot] <296761690+loopover-orb[bot]@users.noreply.github.com>
…8074) Closes #7985. A bare owner reopen of a bot-closed PR stayed excluded from reversalRate (still ambiguous — could be an administrative re-queue), but an owner reopen followed by an approve/merge within 6h is unambiguous: the owner looked again and decided the bot was wrong. Every one of the 2026-07-21/22 metagraphed false-positive incidents (#7469/#7589/#7591/#7594) was exactly this pattern, and the old unconditional owner-reopen exclusion recorded nothing for any of them — part of why the accuracy metric stayed misleadingly high that day. Record a time-bounded owner_reopen_pending_reversal marker on reopen, then promote it to a real reversal_reopened event if a merge follows within OWNER_REOPEN_MERGE_WINDOW_MS. A bot reopening itself still never counts.
…us action (#8092) Closes #7983. The existing self-correction system only detects a systematically- wrong rule via precision-over-time (auto-tune.ts), which needs a real, DECIDED sample (>= AUTOTUNE_MIN_DECIDED) accumulated over however long that takes -- too slow for a bug that can mis-close 4 PRs within hours, as the 2026-07-21/22 metagraphed incident did. A much cheaper, ground-truth-free signal already exists: the SAME deterministic rule/blocker code rejecting several DIFFERENT PRs in a short window in the same repo is itself a strong "something's broken" signal, independent of whether any of those rejections is ever confirmed or reversed by a human. New packages/loopover-engine/src/calibration/signal-tracking.ts: evaluateRuleRepeatAlarm(ruleId, fired, threshold) — pure, no ground truth needed, mirrors src/orb/analytics.ts's gamingPatternFlags precedent ("Detection only — never an automatic action"). New src/review/rule-repeat-alarm-wire.ts wires this into ORB for real: every gate block now records a #7982 rule-fired signal per blocker code (nothing called the ORB adapter until now), scoped per-(repo, code) so an unrelated repo or code never contributes to another's count, and checks the repeat alarm inline, immediately after each block — not on a later cron tick, matching the "hours, not days" urgency the incident exposed. A triggered alarm logs a structured console.error (forwarded to Sentry, the same "detected an anomaly" channel src/review/ops-wire.ts's own runOpsAlerts already uses) and writes a cooldown marker so an ongoing incident doesn't re-alert on every subsequent PR. Note on the issue's own cited alert channel: notify-discord.ts/ notify-slack turned out to be the wrong fit on inspection — that's a per-REPO, community-facing channel for PR action notifications, not an operator-facing "an ORB rule may be systematically broken" signal that can span any repo the instance reviews. Sentry (via the existing structured-log forwarder) is the channel actually already used for this class of alert. Validated against a replay of the exact #7469/#7589/#7591/#7594 incident shape: triggers on the 3rd distinct PR, matching the issue's own "should have alerted after the 2nd or 3rd occurrence" bar.

Summary
Four form controls across the owner / playground / maintainer-settings / digest app panels had no programmatic accessible name — a sibling (non-associated)
<label>or none at all — so a screen reader announced them with no name (WCAG 3.3.2 / 4.1.2). Fixed with association attributes only:htmlFor="owner-repo"on the Repository label + matchingidon the Input.htmlFor/idpairs for the Tool select, Repo input, and Branch input.aria-label="Focus manifest editor"on the JSON textarea.aria-label="Digest notification email"on the email input.Zero visual diff: these are association-attribute-only changes — no layout, style, text, or DOM-nesting change — so nothing rendered changes; the controls only gain a programmatic name.
Tests
Adds one regression test per file (none existed), each asserting the fixed control is reachable by its accessible name via Testing Library
getByLabelText/getByRole({ name })— a real guard against the name regressing.UI Evidence
Playground panel (
/app/playground), dark theme (loopover-ui is a dark-mode-only build — no light theme to capture). The affected Tool / Repo / Branch controls are the labeled fields in the left column. Because the change is attribute-only, before and after are pixel-identical by design — that is the point of the fix: it adds a programmatic accessible name with no visual change.Validation
@loopover/uitypecheck, lint (0 errors), test (163 panel tests pass incl. the 4 new a11y suites), build, and version-audit all green; rebased onto latestmainCloses #7532