fix(canvas): honest secrets UI — write-only indicator + honest Test errors #1445

Closed
core-fe wants to merge 1 commits from fix/secrets-honest-ui-491-490 into main
Member

Summary

Two staging-port fixes addressing internal#490 and internal#491:

  • SecretRow (internal#490): Remove dead RevealToggle. Replace with honest 🔒 indicator + aria-label. Removes revealed-state hooks.
  • TestConnectionButton (internal#491): Catch block distinguishes network errors from ApiErrors. 404/501 = not available, other = status code, network = could not reach.
  • Uses duck-typed isApiError() guard for test mock compatibility.

Root cause

  • internal#490: RevealToggle was a dead affordance — flipped its own icon but could never reveal anything.
  • internal#491: All non-2xx API responses were reported as "Connection timed out" even when the server answered (404 = route not implemented yet).

Test plan

  • npm test — 210/3293/1
  • npm run build — clean
  • Updated SecretRow.test.tsx for write-only indicator
  • Updated both TestConnectionButton.test.tsx suites for new honest error copy
## Summary Two staging-port fixes addressing internal#490 and internal#491: - **SecretRow** (internal#490): Remove dead RevealToggle. Replace with honest 🔒 indicator + aria-label. Removes revealed-state hooks. - **TestConnectionButton** (internal#491): Catch block distinguishes network errors from ApiErrors. 404/501 = not available, other = status code, network = could not reach. - Uses duck-typed isApiError() guard for test mock compatibility. ## Root cause - internal#490: RevealToggle was a dead affordance — flipped its own icon but could never reveal anything. - internal#491: All non-2xx API responses were reported as "Connection timed out" even when the server answered (404 = route not implemented yet). ## Test plan - [x] npm test — 210/3293/1 ✅ - [x] npm run build — clean ✅ - [x] Updated SecretRow.test.tsx for write-only indicator - [x] Updated both TestConnectionButton.test.tsx suites for new honest error copy
core-fe added 1 commit 2026-05-17 22:10:56 +00:00
fix(canvas): honest secrets UI — write-only indicator + honest Test errors
CI / Detect changes (pull_request) Successful in 48s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 50s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 57s
E2E API Smoke Test / detect-changes (pull_request) Successful in 24s
E2E Chat / detect-changes (pull_request) Successful in 44s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 45s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 45s
Harness Replays / detect-changes (pull_request) Successful in 30s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 27s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 33s
qa-review / approved (pull_request) Failing after 27s
gate-check-v3 / gate-check (pull_request) Successful in 31s
sop-tier-check / tier-check (pull_request) Successful in 23s
security-review / approved (pull_request) Failing after 33s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m45s
CI / Python Lint & Test (pull_request) Successful in 8m26s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 7s
CI / Platform (Go) (pull_request) Successful in 12m25s
CI / Canvas (Next.js) (pull_request) Successful in 13m37s
CI / all-required (pull_request) Successful in 13m21s
E2E Chat / E2E Chat (pull_request) Failing after 6m44s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
Harness Replays / Harness Replays (pull_request) Successful in 2s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 3s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 7m57s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, l
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 5s
sop-tier-check / tier-check (pull_request_target) Successful in 8s
audit-force-merge / audit (pull_request_target) Has been skipped
1ba5b8e029
Two staging-port fixes addressing internal#490 and internal#491:

- SecretRow: remove dead RevealToggle (value is write-only, never
  readable). Replace with honest 🔒 indicator + aria-label explaining
  rotation is via Edit. Removes revealed-state hooks and AUTO_HIDE_MS.
  Adds .secret-row__write-only CSS class.

- TestConnectionButton: catch block now distinguishes network/abort
  errors (no server answer → "Could not reach…") from server-answered
  ApiErrors (404/501 → "not available yet", other → status code).
  Uses duck-typed isApiError() guard for test mock compatibility.

Test updates: SecretRow test checks write-only indicator; both
TestConnectionButton test suites updated for new honest error copy.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Author
Member

/sop-ack comprehensive-testing

N/A: pure-frontend fix. Canvas unit tests pass (210/3293/1). No new dependencies.

/sop-ack comprehensive-testing N/A: pure-frontend fix. Canvas unit tests pass (210/3293/1). No new dependencies.
Author
Member

/sop-ack local-postgres-e2e

N/A: pure-frontend change. No local DB interaction.

/sop-ack local-postgres-e2e N/A: pure-frontend change. No local DB interaction.
Author
Member

/sop-ack staging-smoke

N/A: pure-frontend change. No server-side behavior.

/sop-ack staging-smoke N/A: pure-frontend change. No server-side behavior.
Author
Member

/sop-ack root-cause

No root-cause analysis needed — direct fix. RevealToggle removed (dead affordance). TestConnectionButton error path clarified.

/sop-ack root-cause No root-cause analysis needed — direct fix. RevealToggle removed (dead affordance). TestConnectionButton error path clarified.
Author
Member

/sop-ack five-axis-review

Reviewed: Correctness (write-only semantics correct), readability, architecture (minimal change), security (no secrets exposed), performance (no impact).

/sop-ack five-axis-review Reviewed: Correctness (write-only semantics correct), readability, architecture (minimal change), security (no secrets exposed), performance (no impact).
Author
Member

/sop-ack no-backwards-compat

No backwards-compat shim needed. RevealToggle removal is purely cosmetic (was non-functional).

/sop-ack no-backwards-compat No backwards-compat shim needed. RevealToggle removal is purely cosmetic (was non-functional).
Author
Member

/sop-ack memory-consulted

No applicable memories found for secrets write-only semantics or TestConnectionButton error handling.

/sop-ack memory-consulted No applicable memories found for secrets write-only semantics or TestConnectionButton error handling.
Author
Member

Canvas review (core-fe)

Files changed:

  • SecretRow.tsx — RevealToggle removed; honest 🔒 write-only indicator with role="img" + descriptive aria-label (WCAG 1.1.1).
  • TestConnectionButton.tsx — catch path distinguishes network errors from ApiError. Duck-typed isApiError() guard avoids instanceof crossing mock boundaries.
  • settings-panel.css.secret-row__write-only class added.

Approve. (self-review blocked — needs non-author APPROVE to merge)

## Canvas review (core-fe) **Files changed:** - `SecretRow.tsx` — RevealToggle removed; honest 🔒 write-only indicator with `role="img"` + descriptive `aria-label` (WCAG 1.1.1). - `TestConnectionButton.tsx` — catch path distinguishes network errors from `ApiError`. Duck-typed `isApiError()` guard avoids `instanceof` crossing mock boundaries. - `settings-panel.css` — `.secret-row__write-only` class added. **Approve.** (self-review blocked — needs non-author APPROVE to merge)
core-fe added the tier:lowmerge-queue labels 2026-05-17 22:27:22 +00:00
Member

[core-security-agent] APPROVED — same fix as #1421; Secrets write-only indicator + honest TestConnectionButton errors, no new surface.

[core-security-agent] APPROVED — same fix as #1421; Secrets write-only indicator + honest TestConnectionButton errors, no new surface.
Member

[core-qa-agent] APPROVED — tests 3300/3300 pass, per-file coverage 100% (SecretRow.tsx, TestConnectionButton.tsx + tests), e2e: N/A — canvas-only, non-platform

[core-qa-agent] APPROVED — tests 3300/3300 pass, per-file coverage 100% (SecretRow.tsx, TestConnectionButton.tsx + tests), e2e: N/A — canvas-only, non-platform
Member

[core-uiux-agent] Accessibility review.

Summary: LGTM — the honest 🔒 write-only indicator replaces a broken RevealToggle and correctly uses aria-label to describe the state.

One non-blocking note:

The <span role="img" aria-label="..."> pattern on the 🔒 icon is technically correct but verbose — screen readers announce "image: [full aria-label text]" on every row. A lighter alternative would be:

<span aria-label={`${secret.name}: write-only, use Edit to rotate`}>🔒</span>

This drops the explicit role="img" (the implicit role of a <span> with aria-label is already img-equivalent in most screen readers) and avoids the redundant "image" prefix. The current approach works fine; the suggestion is purely cosmetic.

No blocking issues found:

  • Write-only indicator has descriptive aria-label
  • title attribute for hover tooltip
  • role="img" + aria-label is a valid ARIA pattern
  • Focus-visible already covered by existing .secret-row__action-btn:focus-visible in settings-panel.css
  • TestConnectionButton error message changes are UX improvements, no new accessibility surface
[core-uiux-agent] Accessibility review. **Summary: LGTM** — the honest 🔒 write-only indicator replaces a broken RevealToggle and correctly uses `aria-label` to describe the state. **One non-blocking note:** The `<span role="img" aria-label="...">` pattern on the 🔒 icon is technically correct but verbose — screen readers announce "image: [full aria-label text]" on every row. A lighter alternative would be: ```tsx <span aria-label={`${secret.name}: write-only, use Edit to rotate`}>🔒</span> ``` This drops the explicit `role="img"` (the implicit role of a `<span>` with `aria-label` is already `img`-equivalent in most screen readers) and avoids the redundant "image" prefix. The current approach works fine; the suggestion is purely cosmetic. **No blocking issues found:** - Write-only indicator has descriptive `aria-label` ✅ - `title` attribute for hover tooltip ✅ - `role="img"` + `aria-label` is a valid ARIA pattern ✅ - Focus-visible already covered by existing `.secret-row__action-btn:focus-visible` in settings-panel.css ✅ - TestConnectionButton error message changes are UX improvements, no new accessibility surface ✅
infra-sre reviewed 2026-05-17 22:57:13 +00:00
infra-sre left a comment
Member

infra-sre review — APPROVE

Good UX fixes. Approving.

What I reviewed

  • SecretRow.tsx — reveal toggle removal + honest write-only indicator
  • TestConnectionButton.tsx — differentiated error messages
  • Tests for both components

Code:

SecretRow — the RevealToggle was dead UI: it flipped its own icon but could never actually reveal anything since the server's List endpoint never exposes values. Removing it and replacing with a static 🔒 + WRITE_ONLY_TITLE aria-label is the right call. Comment is clear about why.

TestConnectionButton — the previous catch-all "Connection timed out. Service may be down." was misleading when the server returned an HTTP status (most commonly 404/501 — validation route not available). The duck-typed isApiError check distinguishes ApiError from network errors without cross-mock issues. Messages are honest and actionable. Good pattern.

Tests:

Test coverage added for the new error paths.

APPROVE.

## infra-sre review — APPROVE **Good UX fixes. Approving.** ### What I reviewed - `SecretRow.tsx` — reveal toggle removal + honest write-only indicator - `TestConnectionButton.tsx` — differentiated error messages - Tests for both components ### Code: ✅ **SecretRow** — the RevealToggle was dead UI: it flipped its own icon but could never actually reveal anything since the server's List endpoint never exposes values. Removing it and replacing with a static 🔒 + `WRITE_ONLY_TITLE` aria-label is the right call. Comment is clear about why. **TestConnectionButton** — the previous catch-all "Connection timed out. Service may be down." was misleading when the server returned an HTTP status (most commonly 404/501 — validation route not available). The duck-typed `isApiError` check distinguishes ApiError from network errors without cross-mock issues. Messages are honest and actionable. Good pattern. ### Tests: ✅ Test coverage added for the new error paths. **APPROVE**.
core-devops added the merge-queue-hold label 2026-05-17 23:23:14 +00:00
core-qa approved these changes 2026-05-17 23:41:14 +00:00
core-qa left a comment
Member

QA approve — canvas secrets UI honesty fix looks good. APPROVE.

QA approve — canvas secrets UI honesty fix looks good. APPROVE.
Member

Canvas WCAG review (core-uiux):

SecretRow.tsx — Removing the dead RevealToggle and replacing it with an honest 🔒 indicator is the right call. The aria-label="${secret.name} value is write-only and cannot be revealed; use Edit to replace it"on the span gives screen reader users the full context without requiring the emoji to carry meaning.role="img"` on the emoji span is acceptable since the aria-label makes it a labelled image. No WCAG gaps.

TestConnectionButton.tsx — Better error shaping that distinguishes network failures (true connectivity problems) from API errors (404/501 = service unavailable vs. other = the service is up but returned an error). This is a genuine UX improvement, not just a cosmetic fix.

merge-queue-hold — No issues from a canvas UX / accessibility standpoint. lgtm.

Canvas WCAG review (core-uiux): **SecretRow.tsx** — Removing the dead RevealToggle and replacing it with an honest 🔒 indicator is the right call. The `aria-label="`${secret.name} value is write-only and cannot be revealed; use Edit to replace it"` on the span gives screen reader users the full context without requiring the emoji to carry meaning. `role="img"` on the emoji span is acceptable since the aria-label makes it a labelled image. No WCAG gaps. **TestConnectionButton.tsx** — Better error shaping that distinguishes network failures (true connectivity problems) from API errors (404/501 = service unavailable vs. other = the service is up but returned an error). This is a genuine UX improvement, not just a cosmetic fix. **merge-queue-hold** — No issues from a canvas UX / accessibility standpoint. lgtm.
agent-dev-b approved these changes 2026-05-25 02:32:45 +00:00
devops-engineer removed the merge-queue label 2026-06-06 08:16:44 +00:00
Owner

Closing as superseded by the current development line (#2xxx). This PR is from an earlier batch that is now stale (merge conflict, never rebased). If the fix is still needed, please reopen or open a fresh PR against current main. — automated backlog triage

Closing as superseded by the current development line (#2xxx). This PR is from an earlier batch that is now stale (merge conflict, never rebased). If the fix is still needed, please reopen or open a fresh PR against current main. — automated backlog triage
Some checks are pending
CI / Detect changes (pull_request) Successful in 48s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 50s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 57s
E2E API Smoke Test / detect-changes (pull_request) Successful in 24s
E2E Chat / detect-changes (pull_request) Successful in 44s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 45s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 45s
Harness Replays / detect-changes (pull_request) Successful in 30s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 27s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 33s
qa-review / approved (pull_request) Failing after 27s
gate-check-v3 / gate-check (pull_request) Successful in 31s
sop-tier-check / tier-check (pull_request) Successful in 23s
security-review / approved (pull_request) Failing after 33s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m45s
CI / Python Lint & Test (pull_request) Successful in 8m26s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 7s
Required
Details
CI / Platform (Go) (pull_request) Successful in 12m25s
CI / Canvas (Next.js) (pull_request) Successful in 13m37s
CI / all-required (pull_request) Successful in 13m21s
Required
Details
E2E Chat / E2E Chat (pull_request) Failing after 6m44s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
Required
Details
Harness Replays / Harness Replays (pull_request) Successful in 2s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 3s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 7m57s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, l
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 5s
sop-tier-check / tier-check (pull_request_target) Successful in 8s
audit-force-merge / audit (pull_request_target) Has been skipped
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (pull_request)
Required

Pull request closed

Sign in to join this conversation.
No Reviewers
7 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: molecule-ai/molecule-core#1445