19 Commits
Author SHA1 Message Date
Haozhe Wu d6b3db261d fix(channels): finish trusted email delivery and scheduling workflows
Signed-off-by: Haozhe Wu <haozhe_wu@connect.hku.hk>
2026-10-04 03:14:25 +08:00
Haozhe Wu e1dbea8ad3 release: 0.1.16 — a number that can show where it came from
Rolls up 492 commits / 116 merged pull requests since 0.1.15, from 16
contributors.

The final-answer grounding gate stopped guessing what a number is from
the words around it: the model declares each figure's role (observed,
derived, proposed, cited or count), the gate checks the declaration
against the session's tool evidence, and a figure that fails is cut from
the answer instead of the whole answer being refused. A backtest's own
output now grounds the report written about it, run cards cite a metric
only where the saved CSV agrees, and the generated broker matrix states
each profile's permissions as declarations. Research runs keep what they
fetched: compaction follows the model's real context window instead of a
fixed 40K estimate. The missing-data sweep reached 59 more alphas.
Argentina (BYMA), weekly and monthly bars, Bahasa Indonesia, Gildata,
OpenCode, Email and WebSocket channels and four broker connectors (KIS,
Upbit, Toss Securities, Scalable Capital) land alongside.

Verified before release: the reporter's risk-parity prompt, which had
stopped with no_progress after 93 seconds on DeepSeek V4 Pro, completed
on 4a40a7f6's parent in 8m13s with both backtests run, 13 steps saved and
the report released with its core figures grounded.

Version declarations bumped in pyproject.toml, agent/SKILL.md,
Dockerfile, frontend/package.json, both package-lock.json entries, all
nine locales and the Layout test mock. CHANGELOG cites 116/116 merged
pull requests and credits 16/16 authors. README News carries the release
in seven languages, three entries visible.
2026-09-29 16:13:16 +08:00
Haozhe Wu cc54832cb5 release: 0.1.15 — data that says what it is
Rolls up 551 commits / 162 merged pull requests since 0.1.14, from 35
contributors.

Served price frames now stamp the adjustment caliber they carry, and a
source whose caliber was never measured against a live payload reports
`unknown` rather than guessing one. The Alpha Zoo's NaN contract moved out
of the individual alphas and into the registry: an alpha branching on an
`np.where` comparison never sees a NaN, so blanking every declared input on
one bar left 84 of 462 alphas returning a number anyway, each consumed as a
real signal because `dropna()` is what keeps a gap out of an IC. The same
sweep afterwards finds none. The futures loader chain was the last instance
of that class and closes in this release.

New markets and surfaces: UK equities (LSE .L/.IL, SDRT modelled as a
purchase-side-only duty), Zerodha Kite Connect as the fourteenth broker
(paper plus read-only, since Kite exposes no runtime live discriminator), a
read-only multi-broker portfolio across Web / REST / CLI / agent tool,
fifteen Quant Library additions, Brazilian Portuguese as the eighth locale,
read-only Nobitex and Wallex, and an offline evals harness that emits
NOT_EVALUABLE rather than passing when instrumentation is absent.

`test_release_version_consistency.py` caught a fourteenth declaration site
the eleven it was written for did not cover: the `app.version` mock in
`frontend/src/components/layout/__tests__/Layout.test.tsx`. The comment in
`test_cli_update.py` that named the current version is de-versioned here —
a version in a comment has no guard and goes stale at the next bump.

Reader-facing counts were re-measured rather than incremented: 74 MCP tools,
107 registry tools, 10 engines, 90 skills, 462 alphas, 27 data sources, 30
swarm presets, 14 broker connectors. None had drifted.
2026-09-09 15:47:15 +08:00
Haozhe Wu 7329cb096a release: 0.1.14 — a backtest you can read, and Intel Macs that can install
Rolls up 272 commits / 74 merged pull requests since 0.1.13.

Run Detail grows four analysis tabs (factor research, positions structure,
tearsheet, research dashboard) and the Web UI gains an Options Lab, all
reading artifacts a run already writes. `smartmoneyconcepts` moves to an
opt-in `[smc]` extra so an Intel-Mac install stops becoming a CMake source
build for llvmlite. Strategy Discovery lands both phases; scheduled research
delivers itself through a leased outbox and persists each monitor's verdict.

MCP grows to 74 tools. Six READMEs carry the release news and the 30
contributors of this cycle.

Two published version strings had no guard and were still on 0.1.13 after
every other declaration moved: `agent/SKILL.md`, the manifest ClawHub serves
and no build step touches because it is not in the wheel, and the Docker
image's `org.opencontainers.image.version` label. The whole suite stayed
green. `test_release_version_consistency.py` now enumerates all eleven
declaration sites against pyproject rather than spot-checking remembered
ones, and globs the locale directory so a new language is covered the day it
lands. The desktop shell keeps its own 0.3.0 track on purpose — it has no
updater, and 0.3.1 is issue #1016's validation target, not a shipped build.
2026-08-20 07:49:22 +08:00
Haozhe Wu adaeeb5629 fix(docker): pin the build workflow and keep the image on hash-locked dependencies
Four issues in the new workflow and Dockerfile:

- Every action floated on a mutable major tag, and BuildKit was pinned to
  moby/buildkit:master. This was the only workflow in the repo doing so; the
  other four already pin full commit SHAs. All seven actions are now SHA-pinned
  with a version comment, and the custom driver-opts block is dropped, which
  also removes an unneeded network=host.
- id-token: write was granted with no OIDC consumer anywhere in the workflow —
  no cosign, attestation, provenance, or OIDC login step. Dropped.
- The Dockerfile installed channel extras with 'pip install -e ".[extras]"'
  after the --require-hashes lock install. lark-oapi, qrcode and
  python-telegram-bot are in neither requirements-lock.txt nor its source, so
  the build resolved them and their transitive deps unhashed from PyPI at build
  time — six lines below a comment stating deps come from the hash-pinned lock.
  They now come from requirements-channels-lock.txt (16 pins, all hashed,
  generated under the same constraint as the main lock: 12 packages are shared
  with it and none diverge in version). The project install is --no-deps, which
  is safe because all 44 pyproject base deps are already in the main lock.
- The workflow_dispatch input was interpolated directly into the Summary step's
  run: body. It now passes through env, and the tag is validated against the
  Docker tag grammar before any registry work.

CI verifies the new lock too. The existing 'Verify hash-locked dependencies'
step only dry-ran requirements-lock.txt, so a second lock could have rotted
undetected until a release build failed; both are now dry-run separately, since
the Docker build installs them as two independent --require-hashes passes.

The summary also states that a new GHCR package is private until its visibility
is set once, so the pull command it prints is not read as working out of the box.
2026-08-13 15:37:38 +08:00
birdxs 732ee5d2d4 add feishu and telegram channel
add feishu and telegram channel
2026-08-13 08:41:21 +08:00
Haozhe Wu 93edbd7028 fix(agent): gate market answers on verified evidence
Resolve and lock instrument identity before market-sensitive tools, record structured evidence, reject contradictory final numbers, and prepare the 0.1.13 Robinhood serialization patch release.
2026-08-01 16:43:00 +08:00
Haozhe Wu 1e5b79dac6 chore(frontend): move to Node 22 and React Router 8
React Router 7.12.0 through 8.2.x carry a high-severity RSC-mode CSRF bypass
(GHSA-qwww-vcr4-c8h2). We were on 7.18.1, inside that range. The advisory is not
reachable here — the app is a client-side SPA on createBrowserRouter with no
@react-router/server and no RSC entry point, and the frontend ships as static
Vite output — but 7.18.1 is the final 7.x release, no backport exists, and 8.3.0
is the only patched version, so staying put means staying on an EOL line with a
permanent open alert.

react-router-dom has no 8.x at all; the DOM exports moved into react-router
itself. So the dependency is swapped and every import rewritten. All ten APIs in
use here are unchanged in 8.3.0, and none of the data-layer surface that changed
most between majors is used.

react-router 8 requires Node >=22.22.0, which is the same wall that had jsdom 30
and @testing-library/jest-dom 7 sitting in the Dependabot ignore list. Node 20
reached EOL on 2026-04-30, so the toolchain moves to Node 22 across CI, the wiki
workflow, the Dockerfile and docker-compose. That unblocks all three at once:
jsdom and jest-dom are taken here too, and their ignores are removed rather than
left carrying a rationale that no longer holds.

Verified on the frontend suite: tsc -b and vite build clean, 310 tests across 35
files pass before and after the jsdom/jest-dom bumps.
2026-07-28 14:39:59 +08:00
Haozhe Wu 8cb536fa61 chore(release): 0.1.12 — version bump + CHANGELOG
Bump version 0.1.11 → 0.1.12 across pyproject, frontend package(+lock),
i18n app.version, SKILL.md, and Dockerfile OCI label. CHANGELOG [0.1.12]
covers the 0.1.11→0.1.12 window (correlation regime timeline, 3 new LLM
providers, MT5 connector, SDM skill, USD-M perps, ~90 correctness fixes,
and the #758 zai streaming/base_url fix).
2026-07-22 13:14:11 +08:00
Haozhe Wu 4e3c91c77a security: address all 10 findings from external audit (issue #476)
Implements VT-001 through VT-010 from the 2026-07-10 external security
audit (Trivy/Semgrep/ZAP/Gitleaks/pip-audit against a real deployment):

- VT-001 (Critical): AST hardening in backtest/runner.py rejects
  network/subprocess/eval/os.environ/unsafe-open calls reachable from
  generated SignalEngine method bodies (previously only checked
  top-level statements). Defense-in-depth: ephemeral per-run HOME,
  RLIMIT_AS/NOFILE caps, best-effort UID-drop to a new vibe-sandbox
  user (currently inert under Docker's cap model - see session doc;
  accepted as documented residual gap, primary AST defense unaffected).
- VT-002: multi-stage Dockerfile split so build-essential never
  reaches the runtime image.
- VT-003: SSE auth moved from a long-lived API key in the URL query
  string to short-lived single-use tickets; access-log redaction for
  any remaining query secrets.
- VT-004: agent/.env split-brain fixed (bind mount + atomic 0600
  writes) between docker-compose and Web UI settings writes.
- VT-005: /correlation now requires auth + per-IP rate limit; generic
  exceptions no longer leak raw text to clients.
- VT-006: CSP-Report-Only + security headers middleware; Google Fonts
  replaced with self-hosted @fontsource packages.
- VT-007: docker-compose hardening (cap_drop ALL + minimal cap_add,
  no-new-privileges, read_only rootfs, resource limits).
- VT-008: /health split into /live (liveness) and /ready (real
  provider-config readiness check); /health kept as a compat alias.
- VT-009: base images pinned by digest, GitHub Actions pinned by
  commit SHA, dependabot.yml added, hash-verified requirements-lock.txt
  now actually wired into the Docker build via --require-hashes.
- VT-010: universe-panel pickle cache sidecar upgraded from an
  unkeyed SHA-256 (forgeable by anyone with cache-dir write access)
  to a keyed HMAC.

Implemented via a 5-parcel Workflow (file-disjoint, independent
adversarial verification per parcel, then a holistic final audit).
The final audit caught a real regression (CI env-var-gate violation)
and confirmed a dependency-pinning gap, both fixed and re-verified
here, including a latent transitive-dependency bug the fix surfaced
(smartmoneyconcepts<0.0.27 pulls an unbuildable zigzag package) - see
docs/sessions/2026-07-13_session_vt476_security_hardening.md (local,
gitignored) for full evidence trail.

Full suite: 5191 passed, 6 pre-existing/environmental failures
(unchanged from main). Docker build + hardened compose boot verified
end-to-end.
2026-07-13 01:40:53 +08:00
Haozhe Wu 3a9e72f2f6 chore(release): sync infra version strings + requirements for 0.1.11
- Dockerfile OCI version label 0.1.10 -> 0.1.11
- frontend package.json / package-lock.json / 5 i18n locale UI versions -> 0.1.11
- agent/requirements.txt: add bottleneck, defusedxml, prompt_toolkit to match
  pyproject (Docker installs -e . afterwards so images were functionally fine,
  but the cached requirements layer and the file itself had drifted)
2026-07-11 01:17:12 +08:00
Haozhe Wu 2a5557edb6 chore(release): 0.1.10 — version sync + wheel packaging + Docker weasyprint libs (#271)
* chore(release): 0.1.10 — version sync, wheel packaging, Docker weasyprint libs

Release-prep for 0.1.10 (bundles the global data layer + everything since 0.1.9):

- version 0.1.9 -> 0.1.10 synced across all surfaces: pyproject, frontend
  package.json/lock, sidebar footer + i18n, SKILL.md, Dockerfile LABEL. REST
  API + MCP server now derive the version from cli._version (were hardcoded
  "5.0.0" / unset).
- pyproject package-data ships skill example scripts (skills/**/*.py) so the
  wheel + sdist include them; fastmcp floor -> 2.14.0 (first release where the
  MCP version= kwarg applies).
- Dockerfile installs weasyprint native libs (Pango/HarfBuzz/Fontconfig/Cairo/
  gdk-pixbuf + DejaVu) so PDF reports render in the image; .dockerignore *.md
  -> /*.md (root-anchored, skill markdown still ships).
- README news (5 locales): 06-19 reframed as the v0.1.10 release; 06-19/06-18
  trimmed.

Verified: clean-room pip install imports all new loaders/tools; wheel + sdist
carry the eastmoney/sec-edgar skills incl. UTF-8 references + scripts; 4167
backend tests pass (weasyprint PDF path covered on CI).

* docs(release): credit v0.1.10 cycle contributors across READMEs

Refresh the Contributors section in all 5 READMEs from the v0.1.9 cycle to
the v0.1.10 cycle (PRs #162–#260): @Hinotoi-agent, @mvanhorn, @gyx09212214-prog,
@BillDin, @Robin1987China, @LemonCANDY42, @zwrong, @forge-builder, @skloxo,
@LeeCQiang, @KaiLuettmann, @ngoanpv, @ShahNewazKhan, @sambazhu, @bhlt, @octo-patch.
2026-06-19 20:54:20 +08:00
Haozhe Wu 2ba6ae2f0c fix(docker): persist user agent state across container rebuilds
All user-level agent state lives under ~/.vibe-trading in the container
(persistent memory, sessions.db search index, user-created skills,
shadow accounts, hypothesis registry, broker connector config), but
docker-compose only mounted volumes for web sessions and backtest runs.
Every `docker compose up --build` therefore recreated the container and
silently wiped the user's memory store (#197). Swarm run history and
uploads were lost the same way.

- Mount vibe-home -> /home/vibe/.vibe-trading, plus vibe-swarm-runs and
  vibe-uploads.
- Pre-create /home/vibe/.vibe-trading owned by the service user in the
  Dockerfile so the named volume inherits writable permissions (a named
  volume mounted onto a missing path is created root-owned and the
  non-root user cannot write).
- README: document what persists across updates.

Verified end-to-end: memory written via PersistentMemory in one
container is intact in a fresh container on the same volume; the
counterfactual run without the volume reproduces the wipe.

Fixes #197.
2026-06-11 13:17:04 +08:00
Haozhe Wu 6b37c040c1 revert: drop GHCR pre-built image path (#187)
The Path E "pull a pre-built image, no clone" deploy path was open-box
broken: the GHCR package defaults to private, so anonymous `docker pull`
fails, and the path was never verified end-to-end against the main repo
(the contributor tested a self-built image, not ghcr.io/hkuds/vibe-trading).

Removes the publish workflow, docker-compose.prod.yml, the Dockerfile
VERSION arg, and the README Path E section/table row/tree note. The
2026-06-08 news entry is rewritten to cover only the Gemini 3.x
dict-path fix (#184). Also drops the now-orphan edge-build paths-ignore.

If a buildless deploy path is wanted later, do it properly: make the
package public, verify an anonymous pull works, then document it.
2026-06-08 10:45:25 +08:00
Kai LüttmannandCopilot d77f6b3379 feat: publish pre-built image to GHCR on release (closes #183) (#1) (#187)
* feat: publish pre-built image to GHCR on release (#183)

* docs: remove Watchtower references from README

* Add workflow_dispatch trigger to Docker publish workflow

* Allow Docker publish on additional branch

* Update Docker publish workflow triggers

Removed manual trigger and restricted push branches.

---------
authored-by: Kai Lüttmann <33122946+KaiLuettmann@users.noreply.github.com>

Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
2026-06-08 10:12:59 +08:00
Haozhe Wu 946d9ae3b9 chore(release): prepare 0.1.7 2026-05-06 20:08:12 +08:00
Haozhe Wu 9454d4a27a Harden API and tool security defaults 2026-05-03 22:42:20 +08:00
warren618 b0f59bd7f4 fix: Docker build + MCP/PyPI/ClawHub sync (v0.1.4)
- Fix #8: remove COPY data/ data/ from Dockerfile (dir doesn't exist)
- Add akshare/ccxt to requirements.txt and pyproject.toml dependencies
- Remove non-existent run_agent from py-modules
- MCP: rewrite _get_loader to use registry with fallback, add web_search tool (16→17)
- MCP: update docstrings (56→68 skills, add akshare/ccxt source docs)
- ClawHub SKILL.md: 64→68 skills, 3→5 sources, 16→17 tools, add version field
- docker-compose: remove dead fin-data volume, rename fin-→vibe- prefix
- .dockerignore: expand exclusions (tests, docs, assets, build artifacts)
- README: merge 4/10 news, update MCP 16→17, fix contributing (remove done items)
- Bump version 0.1.3→0.1.4, published to PyPI and ClawHub
2026-04-10 22:11:07 +08:00
warren618 34eae37ba4 Initial commit 2026-04-01 18:14:49 +08:00