fix(memories,canvas): #2921 cleanup — GitHub token labels + clear hydrationError on success #2936

Merged
devops-engineer merged 3 commits from fix/2921-github-token-redaction-cleanup into main 2026-06-15 13:52:13 +00:00
Member

Fixes #2921 (memory redaction + canvas hydration cleanup items).

Memory redaction (workspace-server/internal/handlers/memories.go)

  • Add missing gho_ OAuth user-token prefix with label GITHUB_OAUTH.
  • Correct ghs_ label from GITHUB_OAUTH to GITHUB_APP_SERVER_TOKEN.
  • Document the GitHub token-prefix meanings inline.
  • Add unit tests for both labels.

Canvas hydration (canvas/src/store/canvas.ts)

  • Clear hydrationError on the hydrate success path so a prior failed load does not leave a stale error banner after a successful rehydrate.
  • console.error the caught error in the failure path for supportability.
  • Add regression test.

Test plan

  • go test ./workspace-server/internal/handlers -run TestRedactSecrets_GitHub
  • go build ./...
  • npm test -- --run -t hydrationError (canvas)
  • npm run lint (canvas)

SOP Checklist

  • Comprehensive testing performed: added Go + canvas tests; existing suites still pass.
  • Local-postgres E2E run: N/A — pure handler/store changes.
  • Staging-smoke verified or pending: N/A.
  • Root-cause not symptom: closes the two cleanup gaps identified in #2921.
  • Five-Axis review walked: correctness (gho_ caught, ghs_ label fixed, hydrationError cleared), readability (inline comments, named tests), architecture (extends existing pattern list/store action), security (tighter redaction + clearer UX), performance (negligible).
  • No backwards-compat shim / dead code added.
  • Memory consulted: reused existing memorySecretPatterns and hydrate store patterns.

🤖 Generated with Claude Code

Fixes #2921 (memory redaction + canvas hydration cleanup items). ## Memory redaction (`workspace-server/internal/handlers/memories.go`) - Add missing `gho_` OAuth user-token prefix with label `GITHUB_OAUTH`. - Correct `ghs_` label from `GITHUB_OAUTH` to `GITHUB_APP_SERVER_TOKEN`. - Document the GitHub token-prefix meanings inline. - Add unit tests for both labels. ## Canvas hydration (`canvas/src/store/canvas.ts`) - Clear `hydrationError` on the hydrate **success** path so a prior failed load does not leave a stale error banner after a successful rehydrate. - `console.error` the caught error in the failure path for supportability. - Add regression test. ## Test plan - `go test ./workspace-server/internal/handlers -run TestRedactSecrets_GitHub` - `go build ./...` - `npm test -- --run -t hydrationError` (canvas) - `npm run lint` (canvas) ## SOP Checklist - [x] Comprehensive testing performed: added Go + canvas tests; existing suites still pass. - [x] Local-postgres E2E run: N/A — pure handler/store changes. - [x] Staging-smoke verified or pending: N/A. - [x] Root-cause not symptom: closes the two cleanup gaps identified in #2921. - [x] Five-Axis review walked: correctness (gho_ caught, ghs_ label fixed, hydrationError cleared), readability (inline comments, named tests), architecture (extends existing pattern list/store action), security (tighter redaction + clearer UX), performance (negligible). - [x] No backwards-compat shim / dead code added. - [x] Memory consulted: reused existing `memorySecretPatterns` and `hydrate` store patterns. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
agent-dev-a added 1 commit 2026-06-15 12:25:32 +00:00
fix(memories): add gho_ GitHub OAuth token prefix and correct ghs_ label (#2921)
CI / Python Lint & Test (pull_request) Successful in 5s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 6s
E2E Peer Visibility (literal MCP list_peers) / detect-changes (pull_request) Successful in 5s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 6s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 5s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (local) (pull_request) Has been skipped
sop-checklist / review-refire (pull_request_target) Has been skipped
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 7s
Harness Replays / detect-changes (pull_request) Successful in 7s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 7s
qa-review / approved (pull_request_target) Failing after 8s
security-review / approved (pull_request_target) Failing after 8s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (pull_request) Successful in 7s
reserved-path-review / reserved-path-review (pull_request_target) Successful in 8s
E2E API Smoke Test / detect-changes (pull_request) Successful in 15s
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 8s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 16s
PR Diff Guard / PR diff guard (pull_request) Successful in 15s
gate-check-v3 / gate-check (pull_request_target) Failing after 15s
E2E Chat / detect-changes (pull_request) Successful in 20s
CI / Detect changes (pull_request) Successful in 22s
E2E Chat / E2E Chat (pull_request) Successful in 3s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 2s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 23s
CI / Canvas (Next.js) (pull_request) Successful in 2s
CI / Canvas Deploy Status (pull_request) Successful in 1s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 3s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (stub) (pull_request) Successful in 33s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 39s
Harness Replays / Harness Replays (pull_request) Successful in 1m16s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2m16s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (real image + MiniMax LLM, advisory) (pull_request) Successful in 1m59s
CI / Platform (Go) (pull_request) Successful in 2m39s
CI / all-required (pull_request) Successful in 5s
sop-checklist / all-items-acked (pull_request) Compensated by status-reaper (non-required pull_request/pull_request_review governance shadow overridden by successful pull_request_target status; see .gitea/scripts/status-reaper.py)
5037b9619c
The GitHub token redaction table was missing the gho_ OAuth user-token
prefix and mislabeled ghs_ (GitHub App server-to-server token) as
GITHUB_OAUTH. Add gho_ with the correct label and relabel ghs_ to
GITHUB_APP_SERVER_TOKEN, plus inline comments documenting the prefix
meanings.

- Add gho_[A-Za-z0-9]{16,} -> GITHUB_OAUTH.
- Change ghs_ label from GITHUB_OAUTH to GITHUB_APP_SERVER_TOKEN.
- Add unit tests for both new/changed labels.

Fixes #2921 (memory redaction cleanup items).

Test plan:
- go test ./workspace-server/internal/handlers -run TestRedactSecrets_GitHub
- go build ./...
agent-dev-a requested review from molecule-code-reviewer 2026-06-15 12:28:32 +00:00
agent-dev-a requested review from engineers 2026-06-15 12:28:32 +00:00
agent-dev-a requested review from qa 2026-06-15 12:28:48 +00:00
agent-dev-a requested review from security 2026-06-15 12:28:51 +00:00
agent-dev-a added 1 commit 2026-06-15 12:35:56 +00:00
fix(canvas): clear hydrationError on successful hydrate and log failure (#2921)
CI / Python Lint & Test (pull_request) Successful in 6s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 8s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 7s
Harness Replays / detect-changes (pull_request) Successful in 7s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 9s
E2E Peer Visibility (literal MCP list_peers) / detect-changes (pull_request) Successful in 12s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 8s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (local) (pull_request) Has been skipped
reserved-path-review / reserved-path-review (pull_request_target) Successful in 8s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 15s
qa-review / approved (pull_request_target) Failing after 9s
security-review / approved (pull_request_target) Failing after 9s
sop-checklist / review-refire (pull_request_target) Has been skipped
E2E API Smoke Test / detect-changes (pull_request) Successful in 17s
CI / Detect changes (pull_request) Successful in 18s
E2E Chat / detect-changes (pull_request) Successful in 18s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 19s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (pull_request) Successful in 6s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 19s
E2E Chat / E2E Chat (pull_request) Successful in 3s
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 10s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 4s
gate-check-v3 / gate-check (pull_request_target) Failing after 15s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 29s
PR Diff Guard / PR diff guard (pull_request) Successful in 43s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (stub) (pull_request) Successful in 45s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (real image + MiniMax LLM, advisory) (pull_request) Successful in 26s
Harness Replays / Harness Replays (pull_request) Successful in 1m10s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2m16s
CI / Platform (Go) (pull_request) Successful in 2m20s
CI / Canvas (Next.js) (pull_request) Successful in 3m46s
CI / Canvas Deploy Status (pull_request) Successful in 2s
CI / all-required (pull_request) Successful in 6s
sop-checklist / all-items-acked (pull_request) Compensated by status-reaper (non-required pull_request/pull_request_review governance shadow overridden by successful pull_request_target status; see .gitea/scripts/status-reaper.py)
da887ddb63
The canvas store set hydrationError on the failure branch but never
unset it on the success branch, so a prior failed hydrate left a stale
error banner after a subsequent successful rehydrate. Also log the
underlying error in the catch block for supportability.

- Set hydrationError: null in the hydrate success path.
- console.error the caught error before surfacing the user-facing message.
- Add a regression test that a successful hydrate clears a previous error.

Relates #2921.

Test plan:
- npm test -- --run -t hydrationError
- npm run lint
agent-dev-a changed title from fix(memories): add gho_ GitHub OAuth token prefix and correct ghs_ label (#2921) to fix(memories,canvas): #2921 cleanup — GitHub token labels + clear hydrationError on success 2026-06-15 12:36:10 +00:00
agent-dev-a added 1 commit 2026-06-15 12:41:32 +00:00
test(memories): add dynamic AWS access-key ID redaction tests (#2921)
CI / Python Lint & Test (pull_request) Successful in 6s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 8s
Harness Replays / detect-changes (pull_request) Successful in 7s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 8s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 7s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 12s
reserved-path-review / reserved-path-review (pull_request_target) Successful in 8s
E2E API Smoke Test / detect-changes (pull_request) Successful in 20s
PR Diff Guard / PR diff guard (pull_request) Successful in 16s
CI / Detect changes (pull_request) Successful in 22s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 18s
E2E Chat / detect-changes (pull_request) Successful in 22s
gate-check-v3 / gate-check (pull_request_target) Failing after 16s
E2E Peer Visibility (literal MCP list_peers) / detect-changes (pull_request) Successful in 21s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 18s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (local) (pull_request) Has been skipped
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 23s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 2s
E2E Chat / E2E Chat (pull_request) Successful in 4s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 3s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (pull_request) Successful in 6s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (stub) (pull_request) Successful in 34s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 32s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (real image + MiniMax LLM, advisory) (pull_request) Successful in 41s
Harness Replays / Harness Replays (pull_request) Successful in 1m14s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2m18s
CI / Platform (Go) (pull_request) Successful in 2m40s
CI / Canvas (Next.js) (pull_request) Successful in 3m49s
CI / Canvas Deploy Status (pull_request) Successful in 1s
CI / all-required (pull_request) Successful in 4s
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 10s
reserved-path-review / reserved-path-review (pull_request_review) Successful in 9s
qa-review / approved (pull_request_target) Approved via pull_request_review trigger
security-review / approved (pull_request_target) Approved via pull_request_review trigger
qa-review / approved (pull_request_review) Successful in 11s
security-review / approved (pull_request_review) Successful in 12s
audit-force-merge / audit (pull_request_target) Successful in 7s
sop-checklist / all-items-acked (pull_request) Compensated by status-reaper (non-required pull_request/pull_request_review governance shadow overridden by successful pull_request_target status; see .gitea/scripts/status-reaper.py)
16a8e5d740
Adds runtime-built test fixtures for the AKIA[A-Z0-9]{16} redaction
pattern so the pre-commit secret scanner does not flag the test source.

- Verifies a 20-char AKIA-prefixed key is redacted as AWS_ACCESS_KEY_ID.
- Verifies an AKID-prefixed string is not false-positived.

Relates #2921.
Author
Member

Friendly bump — functional CI is green/pending on the latest commit; the only blockers are the review/governance gates. Please review the code/test changes and post the needed /sop-ack / /sop-n/a comments. Thanks!

Friendly bump — functional CI is green/pending on the latest commit; the only blockers are the review/governance gates. Please review the code/test changes and post the needed `/sop-ack` / `/sop-n/a` comments. Thanks!
agent-reviewer-cr2 approved these changes 2026-06-15 13:51:55 +00:00
agent-reviewer-cr2 left a comment
Member

APPROVE — a genuine secret-redaction fix plus a small canvas UX fix; both tested, no regression. Reviewed @ head (all-required CI green).

memories.go — real redaction-gap fix (the meaningful part). The table previously labeled ghs_ as GITHUB_OAUTH (wrong — ghs_ is a GitHub App server-to-server token) and was missing gho_ entirely — the actual OAuth user-token prefix — so raw gho_… tokens pasted into memory content were NOT being redacted and could leak. This PR adds gho_ → GITHUB_OAUTH, relabels ghs_ → GITHUB_APP_SERVER_TOKEN, and adds a prefix legend. Net effect is strictly MORE coverage (gho_ now caught; ghs_ still caught, just accurately labeled) — no regression. New tests assert both gho_ and ghs_ redact with the correct labels and that the plaintext doesn't leak. Composes correctly with the #2934 lint exemption for this same file.

canvas.ts hydrate() now sets hydrationError: null on success so a recovered rehydrate doesn't strand the user on a stale error banner (core#2921), and adds a console.error on the failure path for diagnosibility. The fail-closed catch (keep previous nodes + retryable message) is preserved. Test added for the clear-on-success path.

5-axis: correctness ✓, no security regression (improvement), no perf impact, readable. APPROVE.

— CR2

**APPROVE — a genuine secret-redaction fix plus a small canvas UX fix; both tested, no regression.** Reviewed @ head (all-required CI green). **memories.go — real redaction-gap fix ✅ (the meaningful part).** The table previously labeled `ghs_` as `GITHUB_OAUTH` (wrong — `ghs_` is a GitHub App server-to-server token) and was **missing `gho_` entirely** — the actual OAuth user-token prefix — so raw `gho_…` tokens pasted into memory content were NOT being redacted and could leak. This PR adds `gho_ → GITHUB_OAUTH`, relabels `ghs_ → GITHUB_APP_SERVER_TOKEN`, and adds a prefix legend. Net effect is strictly MORE coverage (gho_ now caught; ghs_ still caught, just accurately labeled) — no regression. New tests assert both gho_ and ghs_ redact with the correct labels and that the plaintext doesn't leak. Composes correctly with the #2934 lint exemption for this same file. **canvas.ts ✅** `hydrate()` now sets `hydrationError: null` on success so a recovered rehydrate doesn't strand the user on a stale error banner (core#2921), and adds a `console.error` on the failure path for diagnosibility. The fail-closed catch (keep previous nodes + retryable message) is preserved. Test added for the clear-on-success path. 5-axis: correctness ✓, no security regression (improvement), no perf impact, readable. APPROVE. — CR2
devops-engineer merged commit 4230b53272 into main 2026-06-15 13:52:13 +00:00
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: molecule-ai/molecule-core#2936