6171f95c19
7 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
| ad7acd30db |
fix(platform): clear golangci-lint findings
Some checks failed
E2E API Smoke Test / detect-changes (pull_request) Successful in 1m0s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 14s
E2E Staging SaaS (full lifecycle) / pr-validate (pull_request) Successful in 54s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 42s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m15s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m50s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 16s
qa-review / approved (pull_request) Failing after 15s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 2m0s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m36s
lint-mask-pr-atomicity / lint-mask-pr-atomicity (pull_request) Successful in 2m8s
gate-check-v3 / gate-check (pull_request) Successful in 32s
security-review / approved (pull_request) Failing after 18s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 41s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 2m11s
sop-checklist-gate / gate (pull_request) Successful in 17s
Harness Replays / Harness Replays (pull_request) Successful in 5s
sop-tier-check / tier-check (pull_request) Successful in 22s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 20s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 14s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 10s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1m42s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 3m53s
CI / Python Lint & Test (pull_request) Successful in 7m18s
CI / Canvas (Next.js) (pull_request) Successful in 11m54s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / Platform (Go) (pull_request) Successful in 12m45s
CI / all-required (pull_request) Successful in 3s
sop-checklist / all-items-acked (pull_request) acked: 7/7
audit-force-merge / audit (pull_request) Successful in 4s
|
|||
|
|
9ceda9d81f |
refactor(events): migrate 18 files to typed EventType constants (RFC #2945 PR-B-1)
Mechanical migration of bare event-name strings in BroadcastOnly / RecordAndBroadcast call sites to the typed constants from internal/events/types.go (RFC #2945 PR-B). Wire format unchanged (both shapes serialize to identical WSMessage.Event literals); pinned by TestAllEventTypes_IsSnapshot in #2965. Migrated (18 files, scope: handlers/, scheduler/, registry/, bundle/, channels/): - handlers/{approvals,a2a_proxy_helpers,a2a_queue,activity,agent, delegation,external_rotate,org_import,registry,workspace, workspace_bootstrap,workspace_crud,workspace_provision_shared, workspace_restart}.go - channels/manager.go (caught by hostile-reviewer pass — initial scope missed channels/, found via grep on the post-migration tree) - scheduler/scheduler.go - registry/provisiontimeout.go - bundle/importer.go Hostile self-review (3 weakest spots, addressed) ------------------------------------------------ 1. Missed call sites — initial scope omitted channels/. Post-migration `grep -rEn 'BroadcastOnly\([^,]+,[^,]*"[A-Z_]+"|RecordAndBroadcast\([^,]+,[^,]*"[A-Z_]+"' internal/` found 2 stragglers in channels/manager.go. Migrated. Final grep on the same pattern returns only the docstring example in types.go (intentional). 2. gofmt drift — auto-import injection produced non-canonical import ordering. `gofmt -w` applied ONLY to the 18 modified files (NOT the whole tree, to avoid sweeping unrelated pre-existing drift into this PR's diff). Three pre-existing un-gofmt'd files in handlers/ (a2a_proxy.go, a2a_proxy_test.go, a2a_queue_test.go) left as-is — they're unchanged by this PR and their drift predates it. 3. Wire format — paranoia check: do the constants serialize to the exact strings consumers (canvas TS, hermes plugin, anything parsing WSMessage.Event) expect? Yes. Pinned by the snapshot test. The migration is name-only; not a single character of wire output changes. Verified - go build ./... clean - go vet ./internal/... clean - gofmt -l on the 5 migrated package dirs: only pre-existing files - Full tests: handlers/, channels/, scheduler/, registry/, events/, bundle/ all green (5 ok, 0 fail) PR-B-2 (canvas TS mirror + cross-language parity gate) remains as the final piece of RFC #2945 PR-B. Tracked separately so this PR stays mechanical + reviewable. Refs RFC #2945, PR #2965 (PR-B types). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
00265d7028 |
feat(channels): first-class Lark/Feishu support via schema-driven config
Lark adapter was already implemented in Go (lark.go — outbound Custom Bot webhook + inbound Event Subscriptions with constant-time token verify), but the Canvas connect-form hardcoded a Telegram-shaped pair of inputs (bot_token + chat_id). Selecting "Lark / Feishu" from the dropdown silently sent the wrong field names — there was no way to enter a webhook URL. Fix: move form shape to the server. - Add `ConfigField` struct + `ConfigSchema()` method to the `ChannelAdapter` interface. Each adapter declares its own fields with label/type/required/sensitive/placeholder/help. - Implement per-adapter schemas: - Lark: webhook_url (required+sensitive) + verify_token (optional+sensitive) - Slack: bot_token/channel_id/webhook_url/username/icon_emoji - Discord: webhook_url + optional public_key - Telegram: bot_token + chat_id (unchanged UX, keeps Detect Chats) - Change `ListAdapters()` to return `[]AdapterInfo` with config_schema inline. Sorted deterministically by display name so UI ordering is stable across Go's random map iteration. - Update the 3 existing `ListAdapters` test sites to struct access. Canvas (`ChannelsTab.tsx`): - Replace the two hardcoded bot_token/chat_id inputs with a single schema-driven `SchemaField` component. Renders one input per field in the order the adapter returns them. - Form state becomes `formValues: Record<string,string>` keyed by `ConfigField.key`. Values reset on platform-switch so stale Telegram credentials can't leak into a new Lark channel. - "Detect Chats" stays but only renders for platforms in `SUPPORTS_DETECT_CHATS` (Telegram only — the only provider with getUpdates). - Only schema-known keys are posted in `config`, scrubbing any stale values from previous platform selections. Regression tests: - `TestLark_ConfigSchema` locks in the 2-field Lark contract with the required/sensitive flags correctly set. - `TestListAdapters_IncludesLark` confirms registry wiring + schema survives round-trip through ListAdapters. Known pre-existing `TestStripPluginMarkers_AwkScript` failure in internal/handlers is unrelated to this change (verified via stash+test on clean staging). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
66ea0b6471
|
test(handlers): add CWE-22 regression suite + KI-005 terminal access fix + tests (#1574)
* fix(lint): unblock Platform Go CI — suppress 8 pre-existing errcheck warnings
golangci-lint errcheck has been flagging these since before this PR —
not regressions from the restart fix, just long-standing debt that
blocks Platform (Go) CI from ever going green. Prefix ignored returns
with `_ =` to make the signal explicit without changing behavior:
- channels/lark_test.go:97 (w.Write) + :118 (resp.Body.Close)
- channels/channels_test.go:620 + :760 (mockDB.Close in t.Cleanup)
- channels/manager.go:131 + :196 (defer rows.Close via closure wrapper)
- channels/manager.go:206–207 (json.Unmarshal into struct fields)
- artifacts/client_test.go:195, 237, 297 (json.Decode in test handlers)
The manager.go defer patch uses `defer func() { _ = rows.Close() }()`
since errcheck doesn't allow the `_ =` prefix directly on `defer`.
Build + `go test ./...` green locally for internal/channels and
internal/artifacts. The manager.go change touches production code so
I re-ran the channels test suite; passes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore: trigger PR refresh
* test(handlers): add CWE-22 regression suite + KI-005 terminal access fix + tests
container_files_test.go (152 lines):
- 11 path-traversal test cases for copyFilesToContainer (F1501/CWE-22)
- Tests nil Docker client — validation logic runs before any Docker call
terminal.go KI-005 security fix (backport from ship/security-fix 6de7530c):
- Enforce CanCommunicate hierarchy check before granting terminal access
- Shell access is more dangerous than A2A message-passing; apply the
same hierarchy check used by A2A and discovery endpoints
- When X-Workspace-ID header is present and bearer token is valid
(ValidateAnyToken), reject unless CanCommunicate(callerID, targetID)
- Canvas/molecli callers without X-Workspace-ID header pass through to
WorkspaceAuth middleware for existing bearer check
- canCommunicateCheck exposed as package var for testability
terminal_test.go (5 test cases):
- TestTerminalConnect_KI005_RejectsUnauthorizedCrossWorkspace
- TestTerminalConnect_KI005_AllowsOwnTerminal
- TestTerminalConnect_KI005_SkipsCheckWithoutHeader
- TestTerminalConnect_KI005_RejectsInvalidToken
- TestTerminalConnect_KI005_AllowsSiblingWorkspace
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Hongming Wang <hongmingwang.rabbit@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Molecule AI Core-BE <core-be@agents.moleculesai.app>
|
||
|
|
2575960805 |
fix(errcheck): suppress unchecked resp.Body.Close() across workspace-server (#1229)
Issue #1196: golangci-lint errcheck flags bare resp.Body.Close() calls because Body.Close() can return a non-nil error (e.g. when the server sent fewer bytes than Content-Length). All occurrences fixed: defer resp.Body.Close() → defer func() { _ = resp.Body.Close() }() resp.Body.Close() → _ = resp.Body.Close() 12 files affected across all Go packages — channels, handlers, middleware, provisioner, artifacts, and cmd. The body is already fully consumed at each call site, so the error is always safe to discard. 🤖 Generated with [Claude Code](https://claude.ai) Co-authored-by: Molecule AI Core-BE <core-be@agents.moleculesai.app> |
||
|
|
af9aae2c38 |
fix(security): cap webhook + config PATCH bodies (H3/H4)
Two HIGH-severity DoS surfaces: both handlers read the entire HTTP body with io.ReadAll(r.Body) and no upper bound, so a caller streaming a multi-gigabyte request could exhaust memory on the tenant instance before we even validated the JSON. H3 (Discord webhook): wrap Body in io.LimitReader with a 1 MiB cap. Discord Interactions payloads are well under 10 KiB in practice. H4 (workspace config PATCH): wrap Body in http.MaxBytesReader with a 256 KiB cap. Real configs are <10 KiB; jsonb handles the cap comfortably. Returns 413 Request Entity Too Large on overflow. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
d8026347e5 |
chore: open-source restructure — rename dirs, remove internal files, scrub secrets
Renames: - platform/ → workspace-server/ (Go module path stays as "platform" for external dep compat — will update after plugin module republish) - workspace-template/ → workspace/ Removed (moved to separate repos or deleted): - PLAN.md — internal roadmap (move to private project board) - HANDOFF.md, AGENTS.md — one-time internal session docs - .claude/ — gitignored entirely (local agent config) - infra/cloudflare-worker/ → Molecule-AI/molecule-tenant-proxy - org-templates/molecule-dev/ → standalone template repo - .mcp-eval/ → molecule-mcp-server repo - test-results/ — ephemeral, gitignored Security scrubbing: - Cloudflare account/zone/KV IDs → placeholders - Real EC2 IPs → <EC2_IP> in all docs - CF token prefix, Neon project ID, Fly app names → redacted - Langfuse dev credentials → parameterized - Personal runner username/machine name → generic Community files: - CONTRIBUTING.md — build, test, branch conventions - CODE_OF_CONDUCT.md — Contributor Covenant 2.1 All Dockerfiles, CI workflows, docker-compose, railway.toml, render.yaml, README, CLAUDE.md updated for new directory names. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |