* docs(i18n): design spec for Russian (ru) language support
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(i18n): register ru locale constant and IsSupported
* feat(i18n): scaffold ru catalog (en placeholders)
* feat(i18n): translate ru backend catalog to Russian
* fix(i18n): polish ru catalog grammar per review
* feat(i18n): wire ru into system messages, config enum, parity test
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(i18n): add ru to web language constants and system-message locales
* feat(i18n): scaffold ru web locale dir (en placeholders)
* feat(i18n): wire ru resources into web i18next config
* feat(i18n): translate ru web locale to Russian (41 namespaces)
* fix(i18n): normalize ru web terminology (арендатор, привязка)
* fix(i18n): restore dropped 'named' in ru setup OAuth hint
* feat(i18n): wire ru into desktop i18next and language pickers
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(i18n): add ru desktop locale (Russian, 16 namespaces)
* test(i18n): extend traces/hooks locale guards to cover ru
* chore(deploy): add repeatable fork-dev local build+deploy tooling
Adds a one-command, idempotent way to run goclaw from a locally built
image that merges fresh upstream dev with un-merged fork features
(Telegram trigger-words PR #1383 + Russian locale), independent of the
published :latest image.
- scripts/deploy-forkdev.sh: fetch origin/dev -> merge feature branches
into local/fork-dev worktree -> push fork/dev -> build -> up -d.
- docker-compose.forkdev.yml: overlay pinning image to goclaw:forkdev
with pull_policy:never so :latest never silently replaces the build.
- .gitignore: track the deploy helper (past deploy-*.sh), ignore the
../.goclaw-forkdev integration worktree.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(telegram): agent-callable message reaction (message action=react)
Adds a "react" action to the message tool so an agent can set an emoji
reaction on an existing message (e.g. mark its own status post 👍 once
fully paid). Mirrors the ChannelEditor wiring: ReactionSetter capability
-> Manager.ReactToMessage -> telegram Channel.ReactToMessage (validates
against Telegram's supported reaction set; ✅/❌ are rejected).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(config): remove ignored session scoping controls (#1405)
Co-authored-by: Collective Developer <man@collective.dev>
* feat(telegram): agent-callable message reaction (message action=react) (#1407)
Adds a "react" action to the message tool so an agent can set an emoji
reaction on an existing message (e.g. mark its own status post 👍 once
fully paid). Mirrors the ChannelEditor wiring: ReactionSetter capability
-> Manager.ReactToMessage -> telegram Channel.ReactToMessage (validates
against Telegram's supported reaction set; ✅/❌ are rejected).
Co-authored-by: skensel <skensel@MacBook-Pro-skensel.local>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* ci: build & publish fork image to GHCR (temporary, pre-upstream)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(memory): use 'russian' FTS config for memory_chunks recall
Memory keyword search (memory_search.go FTS + the generated tsv column)
used the 'simple' text-search config, which does no stemming. Russian
grammatical cases therefore never matched: a genitive query token
("Дианы") could not hit the stored nominative token ("Диана"), so
memory_search returned nothing for natural queries even though the fact
was saved. This is the sole recall path on deployments without an
embedding provider (ChatGPT-OAuth/codex cannot embed), so recall was
effectively dead there.
Switch both sides to the Snowball 'russian' config so index and query
lexemes stem to the same root ("диан"), restoring case-insensitive
recall. Migration 000094 recreates the generated tsv column (a GENERATED
expression cannot be ALTERed in place; ADD COLUMN backfills all rows).
Surface parity: desktop/SQLite N/A — SQLite memory search uses LIKE, a
separate mechanism unaffected by the PG regconfig.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: skensel <skensel@MacBook-Pro-skensel.local>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: ナム <namnhfreelancer@gmail.com>
Co-authored-by: Collective Developer <man@collective.dev>
* feat(ci): deploy zuey beta releases
Add automatic zuey VPS deployment to the dev beta release workflow after prerelease assets are published. Publish beta checksums and make the host upgrade script tolerate beta asset naming and checksum fallback.
* fix(deploy): allow active beta release reruns
Treat an existing target release as success only when it is already the active release and still contains the expected binary and migrations. This keeps automated beta deploy reruns from failing after a prior successful deploy while preserving fail-closed behavior for stale or partial release directories.
Slow tests were dominating CI feedback time and AI dev loop because they
waited through real exponential backoffs and 1s ticker intervals.
Test-only override pattern keeps production behavior 100% identical.
Speed wins (no-race wall-clock per package):
- internal/vault 16.3s -> 0.6s (-15.7s)
- internal/cron 11.7s -> 1.5s (-10.2s)
- internal/channels/facebook 6.3s -> 3.0s (-3.3s)
- Full -race ./... suite 90s+ -> 51s
Changes:
- vault: new fastBackoffsForTest(t) helper overrides enrichRetryBackoffs
+ enrichRetryTimeouts to 1ms in 3 retry tests; drop 2 duplicate tests
(FirstAttemptSuccess, MaxRetriesConstant)
- cron: extract runLoopTickInterval as package var (default 1s); test-only
setFastTick(t) helper shortens to 20ms so 6 scheduler tests no longer
sleep 1.5s each waiting for a tick
- facebook: extract graphBackoffBase as package var (default 1s); newFakeGraph
helper shortens to 1ms so HTTP retry tests don't burn 6s of real waits
Coverage ratchet removed:
- Delete scripts/check_coverage.go + scripts/coverage_thresholds.json
- Remove "Coverage ratchet gate" CI step
- Keep coverage profile + go tool cover summary as informational only
- Philosophy: signal over coverage %. Forced tests to bump % were the
root cause of the slowness this commit unwinds.
Production behavior unchanged. Coverage profile shows isolated package
coverage matches prior thresholds (vault 27.4%, cron 73.7%, facebook 81.9%).
The preserve-loop that backfills threshold entries for packages not
present in the current coverage profile was gated on `!*update`, which
meant `go run scripts/check_coverage.go --update` with a narrow
coverprofile silently wiped floors for every package not measured.
Discovered while ratcheting wave C with a package-scoped profile.
Move the preserve-loop out of the gate so it runs in both check and
update modes. Narrow profiles now touch only observed packages and
leave the rest untouched.
- Add internal/webui/ package with //go:build embedui tag for optional
SPA embedding (handler.go serves static files with SPA fallback)
- Add internal/version/ shared semver comparison (DRY: extracted from
gateway/update_check.go and updater/updater.go)
- Enhance UpdateChecker: release notes, ETag caching, filter lite-v* tags
- Add web UI build stage to Dockerfile with ENABLE_EMBEDUI build arg
- Simplify CI: 7 Docker variants → 4 (base, latest, full, otel)
- Add SHA256 checksums job to release workflow
- Add Makefile build-full target (embeds web UI in Go binary)
- Default make up now embeds web UI (no separate nginx needed)
- Add WITH_WEB_NGINX=1 flag for optional nginx reverse proxy
- Update README + 30 translated READMEs: make up, port 18790
- Update docker-compose comments and prepare-env.sh
- About dialog: show release notes with markdown rendering
- Health card: amber badge for available updates
BREAKING: Default Docker setup no longer requires selfservice overlay.
Web dashboard served at :18790 (same port as API).
The install script only copied the binary, so `goclaw migrate up` and
`goclaw onboard` failed when run from the installed location because the
migrations directory was missing.
- Include migrations/ in the release tarball
- Install migrations to /usr/local/share/goclaw/migrations
- Guide users to export GOCLAW_MIGRATIONS_DIR before onboard
- Align next-steps output with onboard's own instructions