From 8ed892d8638b15864e04bb9674ffca0d25d3f1e8 Mon Sep 17 00:00:00 2001 From: JNHFlow21 Date: Tue, 11 Aug 2026 22:17:31 -0400 Subject: [PATCH] release: prepare TROVE 1.0.0 --- .github/workflows/release.yml | 22 ++++++++++++++++++- CHANGELOG.md | 20 +++++++++++++++++ README.md | 2 ++ README.zh-CN.md | 2 ++ .../tests/test_embedding_provider_contract.py | 5 +++-- scripts/benchmark_agent_runtime.py | 2 +- .../test_agent_runtime_benchmark_contract.py | 11 ++++++++++ 7 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 CHANGELOG.md diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ccc7519..efbb1e0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,15 +6,35 @@ on: - 'v*' permissions: - contents: read + contents: write jobs: release-gate: runs-on: macos-latest steps: - uses: actions/checkout@v7 + with: + fetch-depth: 0 - uses: actions/setup-python@v7 with: python-version: '3.11' - run: bash scripts/bootstrap_runtime.sh - run: ./scripts/trove-python scripts/check.py release + - name: Build and verify distribution + shell: bash + run: | + set -euo pipefail + test "$GITHUB_REF_NAME" = "v1.0.0" + ./scripts/trove-python scripts/build_distribution.py --out dist + ./scripts/trove-python scripts/verify_distribution.py \ + --manifest dist/distribution-manifest.json + - name: Create GitHub release + env: + GH_TOKEN: ${{ github.token }} + shell: bash + run: | + set -euo pipefail + gh release create "$GITHUB_REF_NAME" dist/* \ + --title "TROVE 1.0.0" \ + --notes-file CHANGELOG.md \ + --verify-tag diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..8b261a0 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,20 @@ +# Changelog + +All notable changes to TROVE are documented here. + +## 1.0.0 - 2026-08-11 + +### Added + +- Local-first `trove/1` runtime with CLI, MCP, and owner-only daemon surfaces. +- Bounded recall and search with citations, coverage metadata, cursors, and typed errors. +- Optional, independently packaged WeChat source Provider. +- Human-controlled operation approval and an optional Reply Runtime that is disabled by default. +- Privacy gates, synthetic fixtures, full-history secret scanning, and reproducible distribution manifests. +- English and Simplified Chinese documentation for installation, architecture, operations, and security. + +### Distribution + +- `trove-runtime` 1.0.0 wheel. +- `trove-provider-wechat` 1.0.0 wheel. +- A distribution manifest binding source commit, protocol, package identities, hashes, and privacy flags. diff --git a/README.md b/README.md index 5ff8cac..6fdd3f1 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@

CI status Privacy scan status + Latest GitHub release macOS only Python 3.11 or newer Apache License 2.0 @@ -181,6 +182,7 @@ The scanners are guardrails, not a substitute for human review. See - [Operations and recovery](docs/operations.md) - [Testing](docs/testing.md) - [Release model](docs/release.md) +- [Changelog](CHANGELOG.md) - [Roadmap](docs/roadmap.md) ## Project activity diff --git a/README.zh-CN.md b/README.zh-CN.md index 15122ea..ca11520 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -15,6 +15,7 @@

CI 状态 隐私扫描状态 + 最新 GitHub Release 仅支持 macOS Python 3.11 或更高版本 Apache License 2.0 @@ -145,6 +146,7 @@ gitleaks git --redact - [运维与恢复](docs/operations.md) - [测试](docs/testing.md) - [发行模型](docs/release.md) +- [更新记录](CHANGELOG.md) - [路线图](docs/roadmap.md) ## 项目数据 diff --git a/packages/trove_core/tests/test_embedding_provider_contract.py b/packages/trove_core/tests/test_embedding_provider_contract.py index cd53981..031fc88 100644 --- a/packages/trove_core/tests/test_embedding_provider_contract.py +++ b/packages/trove_core/tests/test_embedding_provider_contract.py @@ -63,12 +63,13 @@ def test_persisted_cloud_policy_never_silently_falls_back_local(self): configured_embedding_provider(vault_root=vault) def test_agent_switch_environment_adds_user_local_bin_for_launch_agents(self): + fixture_home = '/tmp/trove-fixture-home' env = agent_switch_subprocess_environment({ - 'HOME': '/home/example', + 'HOME': fixture_home, 'PATH': '/usr/bin:/bin', 'DASHSCOPE_API_KEY': 'must-not-propagate', }) - self.assertEqual(env['PATH'].split(os.pathsep)[0], '/home/example/.local/bin') + self.assertEqual(env['PATH'].split(os.pathsep)[0], f'{fixture_home}/.local/bin') self.assertEqual(env['PATH'].split(os.pathsep)[1], '/opt/homebrew/bin') self.assertNotIn('DASHSCOPE_API_KEY', env) diff --git a/scripts/benchmark_agent_runtime.py b/scripts/benchmark_agent_runtime.py index 6ca666f..bcb3a1d 100644 --- a/scripts/benchmark_agent_runtime.py +++ b/scripts/benchmark_agent_runtime.py @@ -501,7 +501,7 @@ def main(argv: list[str] | None = None) -> int: parser.add_argument('--warmups', type=int, default=2) parser.add_argument('--seed', type=int, default=20260621) parser.add_argument('--out', default='docs/perf/agent-runtime-budgets.json') - parser.add_argument('--baseline', help='Optional same-host baseline artifact for the 10% p95 regression gate.') + parser.add_argument('--baseline', help='Optional same-host baseline artifact for the 10%% p95 regression gate.') args = parser.parse_args(argv) artifact = run_fixture_baseline(rounds=args.rounds, warmups=args.warmups, seed=args.seed) output = { diff --git a/tests/test_agent_runtime_benchmark_contract.py b/tests/test_agent_runtime_benchmark_contract.py index 3bdec9c..a9ed374 100644 --- a/tests/test_agent_runtime_benchmark_contract.py +++ b/tests/test_agent_runtime_benchmark_contract.py @@ -1,6 +1,8 @@ from __future__ import annotations import unittest +import contextlib +import io import json from pathlib import Path @@ -8,6 +10,7 @@ REQUIRED_MEASUREMENTS, evaluate_absolute_budgets, evaluate_relative_regressions, + main, validate_benchmark_artifact, ) from scripts.measure_agent_surface import estimate_json_tokens @@ -16,6 +19,14 @@ class AgentRuntimeBenchmarkContractTests(unittest.TestCase): + def test_cli_help_renders_on_supported_python_versions(self): + output = io.StringIO() + with contextlib.redirect_stdout(output), self.assertRaises(SystemExit) as raised: + main(['--help']) + self.assertEqual(raised.exception.code, 0) + self.assertIn('10% p95', output.getvalue()) + self.assertIn('regression gate', output.getvalue()) + def _artifact(self) -> dict: measurements = { name: {