Goon
591d809779
Merge remote-tracking branch 'upstream/dev' into dev
...
# Conflicts:
# internal/cron/service.go
2026-06-15 14:14:16 +07:00
Goon
1dea4a21cf
fix: harden media URL handling
2026-06-15 10:20:21 +07:00
Goon
9cd57a920c
feat: add multi-attachment delivery batching
2026-06-12 17:33:54 +07:00
Duy /zuey/ and GitHub
515596c44c
Merge pull request #167 from digitopvn/codex/issue-161-skill-self-evolution
...
feat(skills): add skill self-evolution metrics
2026-06-12 15:55:18 +07:00
Goon
248d591f52
fix: resolve dev merge conflicts
2026-06-12 15:01:38 +07:00
Goon
7692939d09
Merge remote-tracking branch 'origin/dev' into codex/issue-161-skill-self-evolution
...
# Conflicts:
# cmd/skills_cmd.go
# docs/project-changelog.md
# internal/http/skills.go
# internal/store/sqlitestore/schema.go
2026-06-12 14:57:09 +07:00
Goon
f45bfa860c
feat(skills): add skill self-evolution metrics
2026-06-12 14:47:51 +07:00
Goon
c320de5a87
feat: grant first setup agent gateway operator access
2026-06-12 10:40:59 +07:00
Goon
0bf7f88054
feat(skills): add lifecycle API and CLI
2026-06-12 10:38:53 +07:00
Duy /zuey/ and GitHub
9203782ae3
fix(tools): fail closed on github cli credentials ( #154 )
2026-06-11 23:57:56 +07:00
Goon
a63080714a
Merge remote-tracking branch 'upstream/dev' into codex/merge-nextlevelbuilder-goclaw
...
# Conflicts:
# internal/pipeline/think_stage.go
# internal/pipeline/tool_stage.go
# tests/integration/git_adapter_ssh_test.go
2026-06-09 22:38:32 +07:00
thotam
fef98b4dd7
feat(tools): implement piping stream for Gemini File API from video URL
2026-06-06 19:14:13 +07:00
thotam
abb0fab94c
feat(providers): refactor media content representation to separate ImageContent and VideoContent
2026-06-06 18:42:54 +07:00
thotam
0f9dd1f1bc
feat: support passing image URL directly to vision providers in read_image tool
2026-06-06 17:47:46 +07:00
43837afca3
fix(security): consolidate & enhance batched security fixes ( #1155 , #967 , #972 , #974 , #989 , #973 ) ( #1185 )
...
* fix(sandbox): avoid shell in FsBridge writes
Replace sh -c with interpolated path by shell-free 'tee -- <path>' argv form,
piping content via stdin. Prevents command injection through filenames
containing shell metacharacters inside the sandbox container.
Co-authored-by: evgyur <evgyur@gmail.com >
* fix(security): fail-closed on pairing DB errors across channels
On IsPaired lookup error, deny instead of granting access. Covers the shared
CheckDMPolicy/CheckGroupPolicy helpers (Slack/Discord/Feishu/WhatsApp/Zalo) and
the four inline Telegram pairing checks.
Co-authored-by: Srini <srinis.k@gmail.com >
* fix(security): harden provider URL validation against SSRF
Enforce scheme check for all provider types; restrict local types (ollama,
claude_cli, acp) to an explicit localhost allowlist instead of skipping checks;
resolve remote hostnames and reject any IP in a private/reserved range via the
shared security.IsBlocked CIDR list (covers loopback, link-local, metadata,
multicast, and unspecified 0.0.0.0/::). Closes the wildcard-DNS bypass and the
local-type escape hatch. Operator opt-in via GOCLAW_ALLOW_PRIVATE_PROVIDER_URLS.
Exports security.IsBlocked as the single source of truth for blocked ranges.
Co-authored-by: Linh Vo Van <linh.vo@e-cq.net >
* feat(pipeline): add fail-closed tool call authorization gate
Gate tool execution against the server-side AllowedTools allowlist built from the
RBAC/tenant-aware filtered tool set. Resolve the tool-call prefix before the
allowlist lookup so prefixed agents are not wrongly blocked, re-check deny on lazy
MCP activation, and expand IsDenied to cover aliased tool names.
Co-authored-by: Huy Doan <tui@pm.me >
* fix(security): expand file-serve deny-list defense-in-depth
Add absolute-path deny prefixes (/home, /Users, /srv, /var/lib, /var/www, /opt)
and an explicit fail-closed log when no file-serving boundary is configured.
Co-authored-by: Linh Vo Van <linh.vo@e-cq.net >
* fix(providers): allow claude cli executable paths
Refs: #1185
---------
Co-authored-by: evgyur <evgyur@gmail.com >
Co-authored-by: Srini <srinis.k@gmail.com >
Co-authored-by: Linh Vo Van <linh.vo@e-cq.net >
Co-authored-by: Huy Doan <tui@pm.me >
2026-06-05 00:48:38 +07:00
Goon
02d7b6f3de
fix: stabilize agent git access
2026-05-31 19:42:05 +07:00
Goon
994acfe3a4
feat(cli-credentials): add agent-scoped git credentials
2026-05-31 16:49:23 +07:00
Duy /zuey/ and GitHub
9ab3d6dfe5
feat(tools): local-first document extraction for read_document
...
Squash merge PR #111 after resolving docs/changelog conflicts. Local checks covered tools/config and both Go builds; PR CI run 26704622503 passed release-versioning, go, and web.
2026-05-31 12:55:38 +07:00
Duy /zuey/ and GitHub
df8a03df48
fix: allow skill_manage companion files
...
Squash merge PR #104 after validation.
2026-05-31 12:24:22 +07:00
Duy /zuey/ and GitHub
4de94c1d7c
fix(telegram): repair voice transcription routing
...
Squash merge PR #102 after resolving dev changelog conflict. PR CI run 26704061639 passed release-versioning, go, and web.
2026-05-31 12:23:40 +07:00
Duy /zuey/ and GitHub
cf66bda618
fix(rapidapi): add cron credential diagnostics
...
Squash merge PR #101 after resolving dev conflicts and fixing cron GetJob snapshot race. PR CI run 26703877225 passed release-versioning, go, and web.
2026-05-31 12:13:14 +07:00
Duy /zuey/ and GitHub
4ed4eb9509
fix(sandbox): isolate tenant workspace mounts
...
Squash merge PR #100 after resolving changelog conflict with current dev. PR CI run 26703558537 passed release-versioning, go, and web.
2026-05-31 11:55:10 +07:00
Duy /zuey/ and GitHub
a591473546
feat(secure-cli): CLI credential adapters framework + git adapter ( #82 ) ( #89 )
...
* feat(secure-cli): Phase 1 schema + storage delta (issue #82 )
Adds `adapter_name` column to secure_cli_binaries and `credential_type` + `host_scope` columns to secure_cli_user_credentials. LookupByBinary LEFT JOIN now projects AdapterName, UserCredentialType, and UserHostScope. Extends SecureCLIStore with SetUserCredentialsTyped(ctx, binaryID, userID, env, credType, hostScope); legacy SetUserCredentials delegates to typed variant with nil/nil for backward compat.
PG migration 73 + RequiredSchemaVersion bumped to 73. SQLite incremental migrations (versions 39–41) + SchemaVersion 42. 7 SQLite + 6 PG integration tests covering schema, round-trip, NULL legacy, LookupByBinary projection.
Fixes #82
* feat(secure-cli): Phase 2 CredentialAdapter framework + passthrough (issue #82 )
Adds CredentialAdapter interface + Injection{ArgvPrefix,Env,Cleanup,ScrubValues} struct. Registry resolves by name; falls back to passthrough for empty/unknown. passthroughAdapter is default no-op — all existing presets (gh/aws/gcloud/kubectl/terraform/gws) behave bit-for-bit identically.
Per-request WithScrubBag(ctx) + AddScrubValuesCtx + ScrubCredentialsCtx for multi-tenant secret isolation (replaces package-global slice). Hook in executeCredentialed between env merge and exec: resolve adapter by bin.AdapterName, reject non-passthrough in sandbox, call Prepare, splice ArgvPrefix, merge Env, defer Cleanup, register ScrubValues.
Audit log security.system_env_injection records adapter name + env key names + argv_prefix_len + sha256(host_scope) — NEVER values. CLIPreset.AdapterName field added; empty default for legacy presets.
12 unit tests covering passthrough no-op, registry fallback + nil safety, Injection shape, hashHostScope determinism, sortedKeys, scrub bag per-request isolation + concurrent + short-value guard.
Fixes #82
* feat(secure-cli): Phase 2b extensibility helpers + psql stub adapter (issue #82 )
Proves CredentialAdapter framework generalizes beyond git. Adds materializeEphemeral(ctx, content, prefix) shared helper — 0600 tmpfile + idempotent atomic.Bool cleanup latch; memfd intentionally rejected (resolves "self" against child process).
Adds psqlAdapter consuming framework end-to-end via PGPASSFILE pattern; libpq-spec .pgpass escaping for `:` and `\`. Registers psql preset with AdapterName: "psql" (production UI for typed creds lands in v2).
Interface validation gate passes: Injection shape unchanged, hook is psql-agnostic, no special branch needed.
Tests: ephemeral write/cleanup/concurrent/zero-content; psql routing/content/escaping/error paths/registration.
Fixes #82
* feat(secure-cli): git adapter PAT + SSH implementation (issue #82 )
Phase 3 — PAT path
- gitAdapter PAT branch via GIT_CONFIG_COUNT/KEY_0/VALUE_0 env (git 2.31+)
so the token never lands on argv, .git/config, or remote URL
- Host-scope enforcement with IDN normalization (golang.org/x/net/idna)
and embedded-userinfo rejection in URL parsing
- CVE-2018-17456 mitigation: resolve remote URLs via `git config --get`
not `git remote get-url` to dodge ext::sh protocol handler injection
- Case-insensitive DenyArgs blocking `-c http.`, `-c credential.`,
`-c core.sshcommand`, `config --global/--system`, `credential-helper`,
bare `daemon`
- New WithExecCwd / ExecCwdFromContext context helpers — fixes a latent
design gap where the adapter's pre-flight `git config --get` ran in
goclaw's daemon CWD instead of the agent's repo
- 14 unit tests covering subcommand routing, host normalization,
scp-form parsing, userinfo rejection, CRLF token rejection,
CVE-2018-17456 regression, DenyArgs preset coverage
- 3 integration tests against a local TLS git-http-backend server
proving end-to-end clone + fetch + host-mismatch rejection with
zero token leakage into the cloned .git/config
Phase 4 — SSH path
- gitAdapter ssh_key branch materializes per-call 0600 tmpfile via
the Phase 2b materializeEphemeral helper, injects GIT_SSH_COMMAND
with -o IdentitiesOnly=yes -o BatchMode=yes
-o StrictHostKeyChecking=accept-new, idempotent cleanup
- ValidateSSHKey using golang.org/x/crypto/ssh rejects
passphrase-protected keys via ErrSSHKeyPassphraseUnsupported sentinel
- 8 unit tests covering passphrase rejection, env shape, cleanup
lifecycle, host-mismatch reuse, malformed-blob rejection
- 3 integration tests proving tmpfile 0600 lifecycle, env propagation
to child process, cleanup-on-exec-failure, no-orphan-on-rejection
- 2 new i18n keys (en/vi/zh) for SSH-passphrase and SSH-key-invalid
Verification: go vet clean, go build ./... clean,
go build -tags sqliteonly ./... clean, go test -race
./internal/tools/ pass, go test -tags integration
./tests/integration/ -run TestGitAdapter pass.
Refs #82
* feat(secure-cli): UI presets + typed credential HTTP path + i18n (issue #82 )
Phase 5. Typed PUT envelope with {error:{code,message}, error_key} for
field-level errors. CliCredentialGitFields React component (PAT/SSH picker,
host_scope input, CRLF→LF normalization, masked-edit). 17 i18n keys × 3
locales (backend + frontend). i18n parity test.
* feat(secure-cli): audit log schema + adapter framework docs (issue #82 )
Phase 6. emitSystemEnvInjectionAudit helper centralizes
security.system_env_injection slog with host_scope_hash (SHA-256 8 hex,
plaintext hostname omitted for PII safety). Audit shape pinned by
TestEmitSystemEnvInjectionAudit_*. New docs: git-credential-adapter.md
(user guide), credential-adapter-playbook.md (R1 implementer guide w/
kubectl/docker/npm/aws/psql worked mappings). 09-security.md § 14
trust-boundary diagram + SSH TOFU + SIGKILL caveats. 03-tools-system.md
§ 8a. Changelog entry.
* docs(journal): issue #82 CLI credential adapters shipped
Retrospective covering 6 commits across phases 1-6: framework, git PAT/SSH, psql stub, UI/i18n, audit log schema, docs. Notes memfd-drop rationale, TOFU/SIGKILL caveats, sentinel-length lesson from audit-shape tests.
* fix(secure-cli): honor per-request scrub bag on success+failure paths (#82 )
Sandbox and host exec paths called the non-Ctx ScrubCredentials, so
adapter ScrubValues registered into the per-request bag during Prepare
(e.g. GitLab glpat-, Bitbucket app-passwords, Azure DevOps PATs, Gitea
tokens, SSH key tmpfile paths) were ignored on stdout/stderr returned
to the agent. Only the package-global regex pass ran — covering ghp_
but nothing else.
Switch all four exec/sandbox call sites to ScrubCredentialsCtx so the
bag is consulted. Also scrub the slog adapter_cleanup_failed line —
os.Remove errors embed the full tmpfile path.
Add 5 regression tests that pin success path, failure path, negative
control (proves the bag is what catches the sentinel), classic-PAT
sanity, and timeout path no-leak.
Locks AC6 against non-GitHub PAT providers.
* fix(secure-cli): address review-pr #89 findings
- ui/web: SSH key Textarea was 'text-xs' on all viewports, triggering
iOS Safari auto-zoom on focus. Switch to 'text-base md:text-xs' so
mobile renders 16px (no zoom) while desktop keeps compact mono font.
- psql adapter: add on-disk pgpass tmpfile path to ScrubValues. psql
echoes 'could not open password file "<path>"' on IO errors, so
the path needs scrubbing alongside the password. Mirrors the git SSH
adapter pattern. Update test assertion accordingly.
- psql adapter: replace literal 'nil' context with 'context.TODO()'
to silence staticcheck SA1012.
2026-05-28 18:17:49 +07:00
Duy /zuey/ and GitHub
d4463cde6f
fix(exec): surface real cwd error + auto-normalize stale workspace paths ( #77 )
...
* fix(exec): surface chdir error instead of misleading fork/exec
Linux Go forkAndExecInChild conflates chdir + execve failures into one
PathError naming only argv0. When agent workspace points to a stale
directory, exec reports "fork/exec /usr/bin/gh: no such file" even though
the binary exists — the real failure is chdir on cmd.Dir.
Two fixes:
- loop_context.go: fall back to l.workspace when per-user MkdirAll fails
(3 sites: user workspace, dispatched team, auto-resolved team)
- shell.go + credentialed_exec.go: preflight cwd via validateExecCwd
before exec.Command, so the error names the directory, not the binary
Regression test TestValidateExecCwd covers empty / existing / missing /
file-instead-of-dir.
* feat(upgrade): auto-normalize stale agent workspace paths
Detects non-portable workspace values left by deployment migrations
(Docker → bare-metal, host path drift) and rewrites them to the current
configured base. Registered as data hook 072_normalize_agent_workspaces;
runs automatically after `migrate up`.
Stale patterns:
- /app/workspace/* (Docker container path persisted on bare-metal)
- ~ prefix (Go doesn't expand tildes; MkdirAll creates literal ~ dir)
Base resolved with gateway precedence: GOCLAW_WORKSPACE env >
config.Agents.Defaults.Workspace > default ~/.goclaw/workspace.
Idempotent (skips rows already at proposed value). Conservative
(leaves absolute non-stale paths untouched as intentional custom config).
2026-05-27 11:52:25 +07:00
Goon
87b9e296b1
Merge remote-tracking branch 'origin/dev' into codex/configurable-exec-timeout
...
# Conflicts:
# docs/project-changelog.md
2026-05-24 20:19:40 +07:00
Goon
3a749ff91c
Merge remote-tracking branch 'origin/dev' into codex/issue-48-google-workspace-cli
...
# Conflicts:
# docs/project-changelog.md
2026-05-24 18:57:47 +07:00
Goon
3294fccbad
feat(cli): split env visibility for credentials
2026-05-24 15:14:43 +07:00
Duy /zuey/ and GitHub
2bb736cf18
feat(usage): add AI budget usage caps
...
Merge usage-cap budget controls with conflict resolution against dev.
2026-05-24 13:57:31 +07:00
Duy /zuey/ and GitHub
61fdcdcb81
feat(tools): add command keyword allowlist
...
Closes #42
2026-05-24 13:52:23 +07:00
Goon
7fee3073df
merge(dev): resolve usage cap conflicts
2026-05-24 13:49:40 +07:00
Duy /zuey/ and GitHub
5ae5815738
fix(telegram): preserve archive upload paths ( #58 )
2026-05-24 12:48:51 +07:00
Goon
12fb1baf79
feat(runtime): add Google Workspace CLI support
2026-05-24 12:12:16 +07:00
Duy /zuey/ and GitHub
f9440baca2
fix(cron): preserve SecureCLI credential context
...
Closes #54
2026-05-24 09:42:44 +07:00
Goon
9ff5a629d2
feat(usage): add AI budget usage caps
2026-05-23 00:16:03 +07:00
Goon
04d2b4266e
feat(tools): make exec timeout configurable
2026-05-21 16:44:43 +07:00
Duy /zuey/ and GitHub
ce5ea10d46
fix(runtime): repair package installs, archives, logs, and telegram startup
...
Merge runtime/package install fixes, archive attachment handling, operator log access, and Telegram startup IPv4 fallback.
2026-05-20 21:26:10 +07:00
Duy /zuey/ and GitHub
532ff91d8e
fix(security): harden upstream critical surfaces ( #32 )
...
* fix(security): harden upstream critical surfaces
Refs #30
* fix(security): close pre-landing review gaps
Refs #30
* fix(security): close official release blockers
2026-05-20 16:33:49 +07:00
Duy /zuey/ and GitHub
328cbf3d61
Merge pull request #25 from digitopvn/codex/securecli-openrouter-alias
...
fix(secure-cli): resolve runtime npm binary aliases
2026-05-19 10:23:14 +07:00
Goon
a08c626867
fix(secure-cli): resolve runtime npm binary aliases
2026-05-19 09:54:21 +07:00
Goon
ed558e6f89
merge: bring dev into wait tool branch
2026-05-19 09:18:29 +07:00
Duy Nguyen
d48ae43e4f
feat(tools): add built-in wait tool
2026-05-19 06:53:45 +07:00
Duy Nguyen
0d6c5bbb7c
fix(skills): add agent manage grants
...
Add explicit per-agent manage grants for skills so granted agents can patch/delete skills when ownership identity drifts.
Expose skill owner and manage-grant controls in the web skills UI, and add PostgreSQL/SQLite migrations plus coverage for preserve/revoke behavior.
2026-05-17 23:15:52 +07:00
Duy Nguyen
6a253c46ca
fix(test): stabilize ci unit tests
2026-05-17 18:47:46 +07:00
Duy Nguyen
5a189330f9
fix(test): support windows test execution
2026-05-17 15:33:55 +07:00
Duy Nguyen
536ab4ac6c
feat(permissions): add agent channel permission matrix
2026-05-17 15:09:49 +07:00
Duy Nguyen
c029e4f6bf
feat(cli-credentials): support per-agent env grants
...
- enforce binary/grant parent checks on nested grant routes
- validate grant binary/agent tenant scope on create
- fail closed on invalid per-user env and preserve per-user precedence
- remove duplicate CLI Credentials sidebar entry while keeping Packages tab route
- refs #12
2026-05-17 14:35:34 +07:00
Duy /zuey/ and GitHub
4472c607b8
feat(workstation): Remote Workstation Runtime — SSH exec + security + audit ( #4 )
...
* feat(packages): add update flow for GitHub binaries (#900 )
Closes #900 . Proactive update-check + atomic swap for GitHub-installed
binaries on the Runtime & Packages page. Interfaces prepared for pip/npm/apk
extension in Phase 2.
- UpdateCache + UpdateRegistry + PackageLocker (ctx-aware keyed mutex)
- GitHubUpdateChecker: ETag-aware, distinct /latest vs /list ETag keys,
semver-correct ordering via golang.org/x/mod/semver, non-semver fallback
that refuses to downgrade, pre-release + stable candidate fusion for
the v1.0.0-rc.1 -> v1.0.0 transition
- GitHubUpdateExecutor: two-phase .bak swap with hadBackup-aware rollback,
manifest save retry (3x, 100ms/500ms/1s backoff), nil-safe meta access,
explicit ScratchDir, 0755 set pre-rename
- HTTP: GET /v1/packages/updates (SWR), POST /v1/packages/updates/refresh,
POST /v1/packages/update, POST /v1/packages/updates/apply-all
(always 200, failed[] is error source). Master-scope gated.
- WS events package.update.{checked,started,succeeded,failed} forwarded to
owner clients via event_filter.go
- Frontend: useUpdates hook + 3 components (summary bar, update-all modal,
row button), master-scope-gated disabled state
- i18n: 8 backend keys + 17 frontend keys x en/vi/zh
- Config: packages.github_token (reserved), updates_check_ttl, scratch_dir
- 45+ new tests, race-clean, BenchmarkCheckAll10Packages ~1.1ms/op warm
* docs(packages): document update flow + Phase 1 completion
- packages-github.md: "Updating Installed Packages" section with UI + API
contract, troubleshooting runbook (corrupt cache, rate-limit, scratch dir,
mid-swap recovery)
- 17-changelog.md + CHANGELOG.md: Phase 1 entry
- 14-skills-runtime.md: cross-ref to update flow
- journal entry capturing CRIT fixes (double-write, lock-key mismatch,
rollback false-alarm) + design wins (keyed locks, red-team pre-flight)
* feat(workstation): remote workstation runtime — SSH exec + security + audit
Adds generic Remote Workstation Runtime enabling agents to execute commands
on user-owned SSH workstations. Includes registry (DB + API + UI), SSH backend
with connection pool and circuit breaker, workstation.exec + claude_remote tools,
NFKC + binary-name allowlist security, and audit logging.
Standard edition only. Closes #941 .
* fix(workstation): address 3 critical + 5 important code review findings
- C1: Add json:"-" to Metadata/DefaultEnv fields; use SanitizedView() in
all API responses to prevent SSH private key leakage
- C2: Wire CheckEnv into PermCheckFn; LD_PRELOAD/PATH injection now blocked
- C3: SSH Setenv fallback — prepend `export K=V;` when server rejects Setenv
- I1: BackendCache sync.RWMutex → sync.Mutex (fix data race on lastUsed)
- I2: Validate metadata shape in handleUpdate before store write
- I3: Include command in exec-done event; activity sink uses actual cmd hash
- I4: Wrap pool release in sync.Once (idempotent double-call safety)
- I5: Verify workstation tenant ownership before adding permissions
* fix(packages): bypass HTTPS+IP validation in update executor tests
Test httptest servers bind to http://127.0.0.1 which fails both the
HTTPS scheme check and literal-IP SSRF guard. Add testSkipDownloadValidation
flag (same pattern as existing withTestDownloadHosts) to skip full URL
validation in test context.
* fix(workstation): address Claude review findings — tenant isolation + pool leak + dead code
- Activity list: add workstation ownership check before listing
(prevents cross-tenant activity enumeration via known UUID)
- SSH pool: clean up p.sem + p.circuits maps in CloseWorkstation,
prune, and Close to prevent unbounded map growth
- RPC handlers: return ErrInvalidRequest on JSON unmarshal failure
instead of silently using zero-value params
- Remove unused containsControlChars function in normalize.go
- HTTP tests: add 10s context timeout to prevent CI package timeout
* fix(workstation): DefaultEnv JSON parse, backend cache leak, perm ownership check
- DefaultEnv: replace KEY=VALUE text parse with json.Unmarshal (stored as
JSON by HTTP handler, was silently ignored)
- BackendCache: close losing backend on concurrent cache miss to prevent
pruneLoop goroutine leak
- Backend interface: add Close() error method; SSHBackend delegates to
pool.Close()
- handlePermList: add wsStore.GetByID ownership check (prevents cross-tenant
UUID enumeration returning empty array vs 404)
- scanRows: log scan errors instead of silently skipping
* fix(workstation): wire activity sink shutdown + remove misleading comment
- WireActivitySink: capture cleanup func, register in gateway shutdown
(was discarded → retention goroutine leaked + buffered rows lost)
- Add Stop() to WorkstationActivityStore interface (PG+SQLite already had it)
- wireWorkstationTools returns cleanup func; gateway.go defers it
- Remove misleading "re-validate env" comment in allowlist.go Check()
* ci: bump unit test timeout from 90s to 120s
hooks/handlers package (goja script tests) consumes ~85s on cold CI
runners, leaving insufficient headroom for HTTP retry tests with 1s
backoff. 120s provides adequate breathing room without masking real
deadlocks.
* fix: compile errors in integration tests + allowlist docstring
- packages_update_test: add missing lockKey arg to registry.Apply
- mcp_grant_revoke_test: remove unused fakeMCPClient struct
- allowlist.go: fix Check() docstring to match actual 3-step pipeline
* fix(test): relax mcp grant revoke assertion for pre-Phase02 state
Execute-time grant checking not yet wired — test correctly gets an
error but the message is "no active client" (nil clientPtr) rather
than "grant revoked". Accept any error as valid regression guard.
* chore: trigger CI on digitopvn/goclaw fork
* ci: retrigger workflows
* fix(permissions): classify workstation methods in RBAC policy
2026-05-11 14:58:19 +07:00
Duy /zuey/ and GitHub
2c2e01644c
feat(skills): privacy/visibility controls for agent-owned skills ( #1 )
...
* feat(skills): add privacy/visibility controls for agent-owned skills
Closes #1009
- Add private/public visibility enum with validator + normalizer
(internal/skills/visibility.go)
- Add IsSkillVisibleTo/FilterVisibleSkills authorization helper with
three-identity ownership check (actor/user/sender) matching #915
- Propagate owner_id into SkillInfo and all PG/SQLite SELECTs so the
filter has the data it needs
- Agent injection path (FilterSkills, nil allowList) now hides private
skills owned by other users — fixes the leak vector across tenant
members
- publish_skill: accept visibility param (defaults to private), replaces
hardcoded literal
- skill_manage: visibility settable on create and editable via patch,
including a content-less visibility-only patch that skips version bump
- skills.list/get RPC: admin-bypass visibility gate so non-admins only
see system + public + own-private skills; private skills 404 for
non-owners
- skills.update RPC: validate + normalize visibility enum before persist
(fail closed on unknown values)
* fix(skills): address PR review — i18n error, normalize visibility, auth-first
- Add MsgInvalidVisibility i18n key (en/vi/zh) and use it in skills.update
RPC instead of raw validator error text.
- Reorder skills.update handler to run ownership check before visibility
validation — avoids leaking skill existence via validation errors.
- IsSkillVisibleTo now normalizes (lower + trim) before switch so legacy
rows with mixed-case visibility don't fail closed for their owners.
- Extend TestIsSkillVisibleTo with uppercase/whitespace cases.
2026-05-11 13:03:49 +07:00
viettranx
364d2d346f
chore: apply go fix modernizations
2026-04-27 12:00:20 +07:00
viettranx
df5d48c78d
feat(tools/shell): add runtime-reloadable global shell deny-groups via config.tools
...
Adds ToolsConfig.ShellDenyGroups (map[string]bool) so operators can toggle
shell deny groups (package_install, env_dump, etc.) from the /config Web UI
without a process restart.
Wiring:
- ExecTool gains globalDenyGroups + SetGlobalShellDenyGroups (defensive copy).
- effectiveDenyGroups merges per-agent context overrides with global, with
per-key agent precedence — multi-tenant invariant preserved.
- setupToolRegistry applies the initial config before any request can arrive.
- subscribeShellDenyGroupsReload (extracted helper for testability) reacts to
bus.TopicConfigChanged and re-applies the new toggles.
Regression coverage the original PR #1005 attempt missed:
- 6 unit tests for the merge / defensive-copy semantics in internal/tools.
- 3 pub/sub dispatch tests in cmd: happy path, wrong event name, wrong
payload type.
2026-04-24 20:59:08 +07:00