molecule-core/workspace-server/internal/handlers
Hongming Wang dcc870a6b7 feat(workspace-server): server-side chat-history endpoint (RFC #2945 PR-C)
Closes the SSOT gap for chat-history hydration: today every consumer
(canvas TS) re-implements an A2A-envelope walk to map activity_logs
rows into rendered ChatMessage objects. This PR moves that walk into
the server.

## What's added

GET /workspaces/:id/chat-history?limit=N&before_ts=T

Returns:

  {
    "messages": [
      {"id": "<uuid>", "role": "user"|"agent"|"system",
       "content": "...", "attachments": [...], "timestamp": "<RFC3339>"}
    ],
    "reached_end": false
  }

Auth chain: same wsAuth as /workspaces/:id/activity (tenant ADMIN_TOKEN
+ X-Molecule-Org-Id). No new trust boundary.

Filter: a2a_receive rows with source_id IS NULL — same canvas-source
filter the canvas applies via /activity?type=a2a_receive&source=canvas,
centralized so future API consumers don't need to know it.

## What's mirrored from canvas TS

Direct port of canvas/src/components/tabs/chat/historyHydration.ts
+ message-parser.ts:

  - extractRequestText / extractFilesFromUserMessage — user-side parts
    walk through request_body.params.message.parts[]
  - extractChatResponseText — agent-side response_body collector across
    the four shapes (string, A2A JSON-RPC parts, older nested
    parts.root.text, task artifacts) joined with "\n" (matches canvas
    multi-source collector — claude-code emits multiple text parts;
    hermes emits summary+artifacts)
  - extractFilesFromResponse / extractFilesFromTask — file walk across
    parts[] + artifacts[].parts[] + status.message.parts[] +
    message.parts[]
  - v0 hot path ({kind:"file", file:{...}}) AND v1 protobuf flat shape
    ({url, filename, mediaType}) both supported
  - Role decision: status='error' OR text starts with "agent error"
    (case-insensitive) → "system", else "agent"
  - isInternalSelfMessage prefix filter (Delegation results are
    ready...)
  - Timestamp pinned to row.created_at (regression cover for
    2026-04-25 bubble-collapse bug)

## Tests

22 unit tests in chat_history_test.go, every TS test case in
historyHydration.test.ts has a Go counterpart:

  Timestamp preservation (3): user/agent pin to created_at, two-rows
  produce two distinct timestamps.

  User-message extraction (5): text-only, internal-self skip,
  null body, attachments hydrated, attachments-only-when-text-empty,
  internal-self suppresses even with attachments.

  Agent-message extraction (4): result-string, status=error→system,
  agent-error-prefix→system, response_body.parts attachments,
  null body, no-text-no-files-no-bubble.

  End-to-end (1): paired user+agent same timestamp.

  Go-specific (5): malformed JSON returns empty (no panic), v1
  protobuf flat shape extraction, task-artifacts extraction, older
  nested root.text shape, basename helper edge cases.

  isInternalSelfMessage predicate (1): prefix match, non-prefix non-
  match, empty-text non-match.

Mutation-tested. Removed the role-promotion branch (status=error +
agent-error prefix → system); confirmed both
TestChatHistory_RoleSystemWhenStatusError and
TestChatHistory_RoleSystemWhenAgentErrorPrefix fire red. Restored.
Both green.

Full handlers test suite (4.3s) green; full repo `go test ./...` green.

## SSOT decision

Parsing logic lives in workspace-server/internal/handlers/chat_history.go
ONLY. Canvas keeps historyHydration.ts + message-parser.ts during the
transition because:

  - PR-C-2 (follow-up): canvas loadMessagesFromDB swaps to new
    endpoint. Today's canvas still calls /activity for backward
    compatibility.
  - The TS parsers are still load-bearing for LIVE message handling
    (WebSocket A2A_RESPONSE events) until RFC #2945 PR-B-2 mirrors
    the typed event payloads to canvas consumers.

Canvas's TS path will be deleted in a separate PR after a one-week
observation window confirms no live-message consumers depend on it.

## Security review

  - Untrusted input? YES — request_body and response_body come from
    agents (potentially OSS / third-party). Defensive: any malformed
    JSON returns empty content + no attachments, no panic. Tested
    via TestChatHistory_MalformedJSONInRequestBodyReturnsEmpty.
  - Trust boundary? Same as today: agent → workspace-server.
    No new boundary; reuses existing wsAuth middleware.
  - Auth/authz? Inherits wsAuth chain. Cross-workspace access blocked
    by existing TenantGuard middleware.
  - PII / secrets in logs? None. The handler logs nothing on the
    happy path; errors log 502 without body content.
  - Output sanitization? ChatMessage.content is plain text returned
    as-is; canvas already sanitizes via ReactMarkdown. Attachment
    URIs are agent-provided (workspace: / platform-pending: /
    https:); canvas's existing scheme allow-list still applies.

## Versioning / backwards compatibility

  - New endpoint /chat-history. /activity unchanged.
  - Canvas historyHydration.ts + message-parser.ts intact during
    transition (will be removed in PR-C-2 follow-up).
  - No public API consumer of /activity is broken — added route is
    additive.
  - No semver bump (server is internal versioning).

## Three weakest spots (hostile-reviewer self-pass)

1. extractRequestText returns ONLY parts[0].text. If a user message
   contains multiple text parts (uncommon — canvas only ever emits
   one), we lose later parts. Matches canvas exactly today, but a
   future change that emits multi-text user messages needs both
   parsers updated. Documented in code; covered by test if/when
   added.

2. activityRowToChatMessages rebuilds ChatMessage IDs every call (no
   caching). Each chat reload mints fresh UUIDs. This is fine because
   canvas dedupes by (role, content, timestamp window) not id, but a
   future API consumer that DID rely on id stability would break.
   Documented in the ChatMessage struct comment.

3. The handler scopes to source_id IS NULL only (canvas-source rows).
   A future "show all messages, including agent-to-agent" mode would
   need a new endpoint or a parameter. Out of scope for PR-C; canvas's
   /activity?source=canvas already enforces the same filter.

Closes #3017. Unblocks RFC #2945 PR-D (MessageStore interface) which
returns []ChatMessage typed values.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 23:17:26 -07:00
..
testdata fix(workspace-server): vendor upstream derive-provider.sh + close 12-prefix drift 2026-05-02 23:51:23 -07:00
a2a_corpus_test.go test(a2a): protocol-shape replay corpus gate (#2345 follow-up) 2026-04-30 01:26:02 -07:00
a2a_proxy_helpers.go refactor(events): migrate 18 files to typed EventType constants (RFC #2945 PR-B-1) 2026-05-05 19:05:03 -07:00
a2a_proxy_test.go refactor(workspace-status): typed constants + AST-based drift gate 2026-04-30 10:41:41 -07:00
a2a_proxy.go fix(a2a): cover CF 521/522/523 in dead-origin status set 2026-04-30 01:39:04 -07:00
a2a_queue_status_test.go feat(a2a): per-queue-id status endpoint + per-message TTL (RFC #2331 Tier 1) 2026-04-29 20:21:17 -07:00
a2a_queue_status.go feat(a2a): per-queue-id status endpoint + per-message TTL (RFC #2331 Tier 1) 2026-04-29 20:21:17 -07:00
a2a_queue_test.go fix(platform/delegation): classify queued response + stitch drain result back 2026-04-26 10:14:19 -07:00
a2a_queue.go refactor(events): migrate 18 files to typed EventType constants (RFC #2945 PR-B-1) 2026-05-05 19:05:03 -07:00
activity_since_id_test.go feat(activity): since_id cursor on GET /activity (#2339 PR 3) 2026-04-29 22:51:52 -07:00
activity_since_secs_test.go feat(activity): accept ?since_secs= for time-window filtering (#2268) 2026-04-29 05:53:52 -07:00
activity_test.go fix(chat-uploads): activity rows commit atomically with PutBatch 2026-05-05 21:34:28 -07:00
activity.go fix(chat-uploads): activity rows commit atomically with PutBatch 2026-05-05 21:34:28 -07:00
admin_delegations_test.go feat(delegations): operator dashboard endpoint over the durable ledger (RFC #2829 PR-4) 2026-05-04 20:58:17 -07:00
admin_delegations.go feat(delegations): operator dashboard endpoint over the durable ledger (RFC #2829 PR-4) 2026-05-04 20:58:17 -07:00
admin_memories_cutover_test.go fix(admin-memories): include each member's private namespace in export 2026-05-04 09:44:06 -07:00
admin_memories_test.go fix(handlers): unblock Platform (Go) CI — sqlmock budget-check + test loopback 2026-04-22 19:40:06 -07:00
admin_memories.go fix(admin-memories): include each member's private namespace in export 2026-05-04 09:44:06 -07:00
admin_queue_test.go fix(handlers/admin_queue_test): wire sqlmock to make DropStale tests pass 2026-04-24 04:40:19 +00:00
admin_queue.go fix(handlers/admin_queue): remove unused db import 2026-04-24 02:22:16 +00:00
admin_schedules_health_test.go
admin_schedules_health.go
admin_test_token_test.go test(admin_test_token): pin ADMIN_TOKEN IDOR-fix (#112) gate behavior 2026-04-30 02:59:08 -07:00
admin_test_token.go fix(security): close IDOR gaps on /admin/test-token and /orgs/:id/allowlist 2026-04-20 23:29:27 +00:00
admin_workspace_images_test.go feat(platform/admin): /admin/workspace-images/refresh + Docker SDK + GHCR auth 2026-04-26 10:17:21 -07:00
admin_workspace_images.go feat(workspace-server): GHCR digest watcher closes runtime CD chain (#2114) 2026-04-26 13:36:26 -07:00
agent_git_identity_test.go
agent_git_identity.go
agent_message_persistence_gate_test.go test(mcp): comprehensive coverage for send_message_to_user persistence + AST gate (reno-stars followup) 2026-05-05 14:52:32 -07:00
agent_message_writer_test.go fix(handlers): UTF-8-safe preview truncation + distinguish DB errors from not-found (RFC #2945 PR-A followup) 2026-05-05 16:10:58 -07:00
agent_message_writer.go feat(events): typed EventType registry — single source of truth for WS event names (RFC #2945 PR-B) 2026-05-05 16:25:38 -07:00
agent_test.go
agent.go refactor(events): migrate 18 files to typed EventType constants (RFC #2945 PR-B-1) 2026-05-05 19:05:03 -07:00
approvals_test.go
approvals.go refactor(events): migrate 18 files to typed EventType constants (RFC #2945 PR-B-1) 2026-05-05 19:05:03 -07:00
artifacts_test.go
artifacts.go fix(security): replace err.Error() with generic messages in handler responses (#1193) 2026-04-21 00:56:03 +00:00
audit_test.go
audit.go fix: guard HMAC slice truncation in audit chain verification (fixes #1332) (#1339) 2026-04-21 07:52:11 +00:00
budget_test.go
budget.go fix(security): replace err.Error() with generic messages in handler responses (#1193) 2026-04-21 00:56:03 +00:00
bundle.go fix(security): replace err.Error() with generic messages in handler responses (#1193) 2026-04-21 00:56:03 +00:00
channels_test.go
channels.go chore: sync staging to main — 1188 commits, 5 conflicts resolved (#1743) 2026-04-23 18:30:18 +00:00
chat_files_poll_test.go fix(chat-uploads): activity rows commit atomically with PutBatch 2026-05-05 21:34:28 -07:00
chat_files_test.go feat(saas): close 4th default-tier site + lift org_import asymmetry + tests (#2910) 2026-05-05 11:38:22 -07:00
chat_files.go fix(chat-uploads): activity rows commit atomically with PutBatch 2026-05-05 21:34:28 -07:00
chat_history_test.go feat(workspace-server): server-side chat-history endpoint (RFC #2945 PR-C) 2026-05-05 23:17:26 -07:00
chat_history.go feat(workspace-server): server-side chat-history endpoint (RFC #2945 PR-C) 2026-05-05 23:17:26 -07:00
checkpoints_integration_test.go
checkpoints_test.go
checkpoints.go fix(security): replace err.Error() with generic messages in handler responses (#1193) 2026-04-21 00:56:03 +00:00
class1_ast_gate_test.go test(handlers): generic Class 1 leak AST gate (#2867 PR-A) 2026-05-05 13:01:34 -07:00
config_test.go
config.go fix(security): cap webhook + config PATCH bodies (H3/H4) 2026-04-19 01:23:03 -07:00
container_files_delete_test.go chore: sync staging to main — 1188 commits, 5 conflicts resolved (#1743) 2026-04-23 18:30:18 +00:00
container_files_test.go fix(handlers): add empty/dot-only path guard to validateRelPath 2026-04-24 07:17:26 +00:00
container_files.go fix(tests): path validation before docker check + a2a queue mock in tests 2026-04-24 11:07:43 +00:00
delegation_inbox_push_test.go feat(delegations): result-push to caller inbox behind feature flag (RFC #2829 PR-2) 2026-05-04 20:50:46 -07:00
delegation_ledger_integration_test.go test(delegations): tighten integration-test assertions + integrationDB doc (#321) 2026-05-05 03:39:22 -07:00
delegation_ledger_test.go fix(delegation_ledger): rune-safe preview truncation (#2962) 2026-05-05 16:19:51 -07:00
delegation_ledger_writes_test.go feat(delegations): wire ledger Insert+SetStatus from production code paths (RFC #2829 #318) 2026-05-05 02:26:06 -07:00
delegation_ledger_writes.go feat(delegations): wire ledger Insert+SetStatus from production code paths (RFC #2829 #318) 2026-05-05 02:26:06 -07:00
delegation_ledger.go fix(delegation_ledger): rune-safe preview truncation (#2962) 2026-05-05 16:19:51 -07:00
delegation_sweeper_test.go feat(delegations): stuck-task sweeper with deadline + heartbeat-staleness rules (RFC #2829 PR-3) 2026-05-04 20:55:13 -07:00
delegation_sweeper.go feat(delegations): stuck-task sweeper with deadline + heartbeat-staleness rules (RFC #2829 PR-3) 2026-05-04 20:55:13 -07:00
delegation_test.go fix(platform/delegation): classify queued response + stitch drain result back 2026-04-26 10:14:19 -07:00
delegation.go refactor(events): migrate 18 files to typed EventType constants (RFC #2945 PR-B-1) 2026-05-05 19:05:03 -07:00
derive_provider_drift_test.go fix(workspace-server): vendor upstream derive-provider.sh + close 12-prefix drift 2026-05-02 23:51:23 -07:00
discovery_test.go fix(discovery): isSafeURL guard on registered URLs (closes #1484) 2026-04-26 06:50:36 -07:00
discovery.go fix(discovery): isSafeURL guard on registered URLs (closes #1484) 2026-04-26 06:50:36 -07:00
events_test.go
events.go
external_connection_test.go fix(external-connect): use molecule-mcp wrapper in Codex/OpenClaw templates (#2957) 2026-05-05 16:06:02 -07:00
external_connection.go fix(external-connect): use molecule-mcp wrapper in Codex/OpenClaw templates (#2957) 2026-05-05 16:06:02 -07:00
external_rotate_test.go feat(external): credential rotation + re-show instruction modal (#319) 2026-05-05 01:55:27 -07:00
external_rotate.go refactor(events): migrate 18 files to typed EventType constants (RFC #2945 PR-B-1) 2026-05-05 19:05:03 -07:00
github_token_test.go fix(platform-go-ci): align test mocks with schema drift + org_id context contract (#1755) 2026-04-23 07:14:33 +00:00
github_token.go fix(go): replace $1 literal with resp.Body.Close() in 7 files (#1247) 2026-04-21 03:18:21 +00:00
handlers_additional_test.go refactor(workspace-status): typed constants + AST-based drift gate 2026-04-30 10:41:41 -07:00
handlers_extended_test.go refactor(workspace-status): typed constants + AST-based drift gate 2026-04-30 10:41:41 -07:00
handlers_test.go feat: drop shared_context — use memory v2 team namespace instead 2026-05-04 16:30:26 -07:00
hermes_messages_test.go
hermes_messages.go
hibernation_test.go refactor(workspace-status): typed constants + AST-based drift gate 2026-04-30 10:41:41 -07:00
instructions.go fix(review): address code review blockers on tool-trace + instructions 2026-04-22 16:18:06 -07:00
mcp_test.go test(mcp): comprehensive coverage for send_message_to_user persistence + AST gate (reno-stars followup) 2026-05-05 14:52:32 -07:00
mcp_tools_memory_legacy_shim_test.go Memory v2 PR-6: backward-compat shim — legacy tools route to v2 2026-05-04 08:01:41 -07:00
mcp_tools_memory_legacy_shim.go Memory v2 PR-6: backward-compat shim — legacy tools route to v2 2026-05-04 08:01:41 -07:00
mcp_tools_memory_v2_test.go Memory v2 fixup I1+I4: expires_at validation + audit JSON marshal 2026-05-04 08:57:58 -07:00
mcp_tools_memory_v2.go Memory v2 fixup I1+I4: expires_at validation + audit JSON marshal 2026-05-04 08:57:58 -07:00
mcp_tools.go refactor(handlers): consolidate Notify + MCP send_message_to_user through AgentMessageWriter (RFC #2945 PR-A) 2026-05-05 15:29:42 -07:00
mcp.go Memory v2 PR-11: E2E test — flat-plugin swap proves contract works 2026-05-04 08:20:35 -07:00
memories_test.go feat(memories): PATCH /workspaces/:id/memories/:id endpoint for edits 2026-05-04 21:00:47 -07:00
memories_v2_test.go fix(memory-v2): namespace dropdown labels use display names not UUID prefixes (#2988) 2026-05-05 18:46:50 -07:00
memories_v2.go fix(memory-v2): namespace dropdown labels use display names not UUID prefixes (#2988) 2026-05-05 18:46:50 -07:00
memories.go feat(memories): PATCH /workspaces/:id/memories/:id endpoint for edits 2026-05-04 21:00:47 -07:00
memory_test.go
memory.go fix(security): replace err.Error() with generic messages in handler responses (#1193) 2026-04-21 00:56:03 +00:00
native_session_test.go feat(runtime): native_session skips a2a_queue enqueue — primitive #5 of 6 2026-04-26 23:34:04 -07:00
native_status_mgmt_test.go refactor(workspace-status): typed constants + AST-based drift gate 2026-04-30 10:41:41 -07:00
org_helpers.go fix: CWE-78 rm scope, go vet failures, delegation idempotency 2026-04-21 18:22:30 +00:00
org_import_force_removed_test.go fix(org-import): remove force=true bypass of required-env preflight 2026-04-29 03:23:23 -07:00
org_import_idempotency_test.go fix(workspace-server): close TOCTOU race on workspaces(parent_id, name) (#2872 Critical 1) 2026-05-05 21:43:49 -07:00
org_import.go fix(workspace-server): close TOCTOU race on workspaces(parent_id, name) (#2872 Critical 1) 2026-05-05 21:43:49 -07:00
org_include_test.go fix(platform-go-ci): align test mocks with schema drift + org_id context contract (#1755) 2026-04-23 07:14:33 +00:00
org_include.go
org_path_test.go
org_plugin_allowlist_test.go fix(platform-go-ci): align test mocks with schema drift + org_id context contract (#1755) 2026-04-23 07:14:33 +00:00
org_plugin_allowlist.go fix(platform-go-ci): align test mocks with schema drift + org_id context contract (#1755) 2026-04-23 07:14:33 +00:00
org_prompt_ref_test.go
org_provision_concurrency_test.go feat(org-import): make provision concurrency configurable via env 2026-05-04 16:33:49 -07:00
org_test.go feat(org-templates): add ux-ab-lab + manifest entry + schema smoke test 2026-04-24 16:22:14 -07:00
org_tokens_test.go fix(platform-go-ci): align test mocks with schema drift + org_id context contract (#1755) 2026-04-23 07:14:33 +00:00
org_tokens.go fix(platform): unblock SaaS workspace registration end-to-end 2026-04-21 03:06:46 -07:00
org.go feat(org-import): make provision concurrency configurable via env 2026-05-04 16:33:49 -07:00
pending_uploads_integration_test.go test(chat-uploads): integration test for cross-table atomicity (#149 follow-up) 2026-05-05 21:57:56 -07:00
pending_uploads_test.go fix(chat-uploads): activity rows commit atomically with PutBatch 2026-05-05 21:34:28 -07:00
pending_uploads.go feat(rfc): poll-mode chat upload — phase 1 platform staging layer 2026-05-05 04:22:24 -07:00
plugins_install_pipeline_test.go
plugins_install_pipeline.go test(plugins): unblock TestResolveAndStage_NoInternalErrorsInHTTPErr (#1814) 2026-04-27 04:00:39 -07:00
plugins_install.go fix(security): replace err.Error() with generic messages in handler responses (#1193) 2026-04-21 00:56:03 +00:00
plugins_listing.go
plugins_sources.go
plugins_test.go fix(platform-go-ci): align test mocks with schema drift + org_id context contract (#1755) 2026-04-23 07:14:33 +00:00
plugins.go test(plugins): unblock TestResolveAndStage_NoInternalErrorsInHTTPErr (#1814) 2026-04-27 04:00:39 -07:00
provlog_emit_test.go feat(workspace-server): structured logging at provisioning boundaries 2026-05-05 12:30:11 -07:00
registry_test.go fix(workspace): deliver platform_inbound_secret on every heartbeat 2026-04-30 17:36:33 -07:00
registry.go refactor(events): migrate 18 files to typed EventType constants (RFC #2945 PR-B-1) 2026-05-05 19:05:03 -07:00
restart_context_test.go
restart_context.go
restart_template_test.go chore(manifest): prune to 4 actively-supported runtimes 2026-05-02 19:21:47 -07:00
restart_template.go fix(handlers): apply sanitizeRuntime allowlist before Tier 4 filepath.Join (CWE-22) 2026-04-24 11:37:19 +00:00
runtime_image_pin_test.go feat(provisioner): digest-pin workspace images via runtime_image_pins (#2272 layer 1) 2026-05-03 02:30:00 -07:00
runtime_image_pin.go feat(provisioner): digest-pin workspace images via runtime_image_pins (#2272 layer 1) 2026-05-03 02:30:00 -07:00
runtime_overrides_test.go feat(runtime): native_scheduler skip — primitive #3 of 6 2026-04-26 22:47:00 -07:00
runtime_overrides.go feat(runtime): native_scheduler skip — primitive #3 of 6 2026-04-26 22:47:00 -07:00
runtime_provision_timeouts_test.go feat(workspace-server): surface provision_timeout_ms in workspace API (#2054 phase 2) 2026-04-26 06:37:45 -07:00
runtime_provision_timeouts.go refactor(handlers): apply simplify findings on PR #2094 2026-04-26 06:40:15 -07:00
runtime_registry_test.go feat(external-runtime): first-class BYO-compute workspaces + manifest-driven registry 2026-04-24 15:34:10 -07:00
runtime_registry.go chore(manifest): prune to 4 actively-supported runtimes 2026-05-02 19:21:47 -07:00
saas_default_tier_test.go feat(saas): close 4th default-tier site + lift org_import asymmetry + tests (#2910) 2026-05-05 11:38:22 -07:00
sanitize_filename_test.go feat(rfc): poll-mode chat upload — phase 1 platform staging layer 2026-05-05 04:22:24 -07:00
schedules_test.go
schedules.go fix(security): replace err.Error() with generic messages in handler responses (#1193) 2026-04-21 00:56:03 +00:00
secrets_test.go feat(workspace-server): PUT /provider endpoint for explicit LLM provider (#196) 2026-04-30 22:25:48 -07:00
secrets.go fix(workspace-server): persist canvas-selected model + provider on first deploy 2026-05-02 19:21:01 -07:00
security_regression_685_686_687_688_test.go feat(saas): close 4th default-tier site + lift org_import asymmetry + tests (#2910) 2026-05-05 11:38:22 -07:00
socket.go
sse_test.go
sse.go
ssrf_test.go test(ssrf): pin dev-mode RFC-1918 allow contract (follow-up to #2103) 2026-04-26 10:32:33 -07:00
ssrf.go fix(platform/ssrf): allow RFC-1918 in MOLECULE_ENV=development 2026-04-26 10:14:47 -07:00
template_files_eic_dispatch_test.go fix(workspace files API): EIC parity for ListFiles + DeleteFile (closes #2999 PR-A) 2026-05-05 20:18:05 -07:00
template_files_eic_shells_test.go fix(workspace files API): EIC parity for ListFiles + DeleteFile (closes #2999 PR-A) 2026-05-05 20:18:05 -07:00
template_files_eic_test.go fix(workspace files API): EIC parity for ListFiles + DeleteFile (closes #2999 PR-A) 2026-05-05 20:18:05 -07:00
template_files_eic.go fix(workspace files API): EIC parity for ListFiles + DeleteFile (closes #2999 PR-A) 2026-05-05 20:18:05 -07:00
template_import_test.go feat(saas): close 4th default-tier site + lift org_import asymmetry + tests (#2910) 2026-05-05 11:38:22 -07:00
template_import.go fix(workspace files API): EIC parity for ListFiles + DeleteFile (closes #2999 PR-A) 2026-05-05 20:18:05 -07:00
templates_test.go fix(workspace files API): EIC parity for ListFiles + DeleteFile (closes #2999 PR-A) 2026-05-05 20:18:05 -07:00
templates.go fix(workspace files API): EIC parity for ListFiles + DeleteFile (closes #2999 PR-A) 2026-05-05 20:18:05 -07:00
terminal_diagnose_test.go fix(terminal-diagnose): KI-005 hierarchy check + race-free stderr capture 2026-04-30 21:19:18 -07:00
terminal_diagnose.go fix(terminal-diagnose): KI-005 hierarchy check + race-free stderr capture 2026-04-30 21:19:18 -07:00
terminal_test.go test(terminal): update exact-argv snapshot to include ConnectTimeout 2026-04-30 20:23:48 -07:00
terminal.go fix(terminal): cap ssh handshake at 10s so hung sshd surfaces fast 2026-04-30 20:16:41 -07:00
tokens_sqlmock_test.go test(handlers): sqlmock coverage for tokens.go (closes #1819) 2026-04-26 02:50:42 -07:00
tokens_test.go
tokens.go
traces_test.go
traces.go fix(go): replace $1 literal with resp.Body.Close() in 7 files (#1247) 2026-04-21 03:18:21 +00:00
transcript_test.go
transcript.go fix(go): replace $1 literal with resp.Body.Close() in 7 files (#1247) 2026-04-21 03:18:21 +00:00
viewport_test.go
viewport.go fix(security): replace err.Error() with generic messages in handler responses (#1193) 2026-04-21 00:56:03 +00:00
webhooks_test.go fix(platform-go-ci): align test mocks with schema drift + org_id context contract (#1755) 2026-04-23 07:14:33 +00:00
webhooks_workflow_test.go
webhooks.go fix: multiple platform handler bug fixes 2026-04-20 05:01:01 +00:00
workspace_bootstrap_test.go refactor(workspace-status): catch missed literal in workspace_bootstrap.go + add literal-drift gate 2026-04-30 10:51:01 -07:00
workspace_bootstrap.go refactor(events): migrate 18 files to typed EventType constants (RFC #2945 PR-B-1) 2026-05-05 19:05:03 -07:00
workspace_budget_test.go feat(workspaces): delivery_mode column + poll-mode register flow (#2339 PR 1) 2026-04-29 21:47:14 -07:00
workspace_crud.go refactor(events): migrate 18 files to typed EventType constants (RFC #2945 PR-B-1) 2026-05-05 19:05:03 -07:00
workspace_dispatchers.go feat(workspace-server): structured logging at provisioning boundaries 2026-05-05 12:30:11 -07:00
workspace_metrics_test.go
workspace_metrics.go
workspace_namespace_cleanup_test.go Memory v2 fixup I5: workspace purge cleans up plugin namespace 2026-05-04 09:20:37 -07:00
workspace_preflight_test.go chore: code-review cleanup on today's shipped PRs 2026-04-20 16:04:57 -07:00
workspace_preflight.go chore: code-review cleanup on today's shipped PRs 2026-04-20 16:04:57 -07:00
workspace_provision_auto_test.go Merge pull request #2856 from Molecule-AI/chore/remove-team-expand-handler 2026-05-05 09:42:51 +00:00
workspace_provision_concurrent_repro_test.go test(provision): tighten Assertion 4 message to name both failure modes 2026-05-01 20:14:39 -07:00
workspace_provision_panic_test.go test(provision): harden panic tests with re-raise guard + assert broadcast count 2026-05-01 20:11:11 -07:00
workspace_provision_shared_test.go fix(workspace-server): vendor upstream derive-provider.sh + close 12-prefix drift 2026-05-02 23:51:23 -07:00
workspace_provision_shared.go refactor(events): migrate 18 files to typed EventType constants (RFC #2945 PR-B-1) 2026-05-05 19:05:03 -07:00
workspace_provision_test.go feat(provisioner): digest-pin workspace images via runtime_image_pins (#2272 layer 1) 2026-05-03 02:30:00 -07:00
workspace_provision.go refactor(models): consolidate per-runtime model defaults to SSOT (RFC #2873 iter 1) 2026-05-05 04:12:37 -07:00
workspace_restart_async_test.go Move /restart Stop into the async goroutine 2026-04-30 19:35:29 -07:00
workspace_restart_coalesce_test.go fix(restart): clear running flag on panic in cycle() 2026-04-29 00:00:12 -07:00
workspace_restart_stop_retry_test.go fix(restart): retry cpProv.Stop with backoff + flag exhaustion as LEAK-SUSPECT 2026-05-01 23:36:38 -07:00
workspace_restart_test.go fix(workspace-server): skip provision pipeline on Restart for runtime=external 2026-04-30 15:08:48 -07:00
workspace_restart.go refactor(events): migrate 18 files to typed EventType constants (RFC #2945 PR-B-1) 2026-05-05 19:05:03 -07:00
workspace_test.go fix(workspace-server): emit null removed_at when timestamp fetch fails 2026-04-30 22:24:59 -07:00
workspace.go refactor(events): migrate 18 files to typed EventType constants (RFC #2945 PR-B-1) 2026-05-05 19:05:03 -07:00
workspaces_insert_allowlist_test.go test(handlers): allowlist INSERT INTO workspaces sites — close bulk-create regression class (#2867 class 1) 2026-05-05 11:15:16 -07:00