Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
a890511
chore: pin the core dependency to a tag instead of tracking main (#25)
fylorn Sep 23, 2026
a90e9f3
feat!: forward what can be forwarded, convert only what must be (#26)
fylorn Sep 23, 2026
ca7647c
refactor: take the circuit-breaker registry and metric labels back fr…
fylorn Sep 23, 2026
a6678cf
refactor: redact PII with core's guard engine, and restore tool argum…
fylorn Sep 23, 2026
437a671
feat: inspect the tool calls an upstream returns (#29)
fylorn Sep 23, 2026
038796b
build: keep only line tables in dev and test builds (#30)
fylorn Sep 24, 2026
05f52e8
feat: one circuit-breaker state machine, and hidden characters in req…
fylorn Sep 24, 2026
8a76395
fix: make the integration suite pass again (#32)
fylorn Sep 24, 2026
6482690
test: fix the two flaky integration tests (#33)
fylorn Sep 24, 2026
9f46116
fix: bill a Chat stream whose caller did not ask for usage (#34)
fylorn Sep 24, 2026
3c35ab8
fix: a request the upstream refuses no longer fails over or trips bre…
fylorn Sep 24, 2026
234fcce
Merge main (v1.1.0) into dev
fylorn Sep 24, 2026
82f8061
docs: cut releases from a release branch, and keep the tag's headings…
fylorn Sep 24, 2026
bd57b5d
ci: run checks on pull requests into dev, including the integration s…
fylorn Sep 24, 2026
c1b2085
fix: bill cached input at cache prices, estimate missing usage, strip…
fylorn Sep 24, 2026
ad5b75b
refactor: take back what only this side used from core (#41)
fylorn Sep 24, 2026
3a617f3
feat(gateway): take official hosts, output fallback and error shapes …
fylorn Sep 24, 2026
ed1c8b5
feat(gateway): accept Gemini clients, and the Responses API over a We…
fylorn Sep 24, 2026
28d4387
test: count the probes that miss before the streaming cache hit (#44)
fylorn Sep 24, 2026
d3f36fc
refactor(server): move the catalog's SQL into repositories (#45)
fylorn Sep 24, 2026
83e9bcc
refactor(server): move the dashboard, limits and log-forwarding handl…
fylorn Sep 24, 2026
9b5b326
refactor(server): move the MCP handlers' SQL into repositories (#50)
fylorn Sep 24, 2026
86beb82
refactor(gateway): run the request guards on core's tw-guard engines …
fylorn Sep 24, 2026
1c80b83
refactor(server): move the identity handlers' SQL into repositories (…
fylorn Sep 24, 2026
c25b44f
fix(mcp): revoking a default connection no longer fails with a 500 (#51)
fylorn Sep 24, 2026
dbce845
test: leave the cancelled stream after it has started, not on a timer…
fylorn Sep 24, 2026
c3d2d57
refactor(server): move the access handlers' SQL into repositories (#48)
fylorn Sep 24, 2026
d92c2d1
fix(settings): read security.totp_required as a boolean, and seed aut…
fylorn Sep 24, 2026
7e95183
feat(gateway): record a client that leaves before its response exists…
fylorn Sep 24, 2026
367df3c
feat(auth): enforce the TOTP requirement (#55)
fylorn Sep 24, 2026
443de8d
feat(gateway): keep the last response on a Responses WebSocket (#56)
fylorn Sep 24, 2026
6890c72
Merge main (v2.0.0) into dev
fylorn Sep 24, 2026
d4f6d5a
docs(release): CI runs the integration suite on the release PR (#58)
fylorn Sep 24, 2026
ef3de87
docs(contributing): point vulnerability reports at the organization's…
fylorn Sep 25, 2026
c4f8b1c
docs(readme): current description of ThinkWatch Lite and ThinkWatch C…
fylorn Sep 25, 2026
f259962
feat(providers): authenticate Bedrock with an API key (#61)
fylorn Sep 28, 2026
78f9ab5
test: hold the early-cancel client once its key is known, not on a ti…
fylorn Sep 28, 2026
1b752f2
feat(providers): list Bedrock's models, and let the route editor take…
fylorn Sep 28, 2026
1f08421
fix(bedrock): refuse keys that will not decrypt, and keep instance-ro…
fylorn Sep 28, 2026
e480bfd
refactor(bedrock): use core's shared tw-bedrock, and core v0.55.0 (#65)
fylorn Sep 29, 2026
e1e7999
docs(readme): rewrite both READMEs to be short and accurate (#66)
fylorn Sep 30, 2026
af9eb81
Merge main (v2.1.0) into dev
fylorn Sep 30, 2026
ed6dd39
docs(readme): 37 MCP templates, what the setup wizard does, body reda…
fylorn Sep 30, 2026
9afcc08
fix(rbac): make the seeded team_manager work at team scope (#69)
fylorn Sep 30, 2026
fa3a5b9
fix(rbac): require gateway use, and count only grants that give it (#70)
fylorn Sep 30, 2026
a1eed6f
Merge main (v2.2.0) into dev
fylorn Sep 30, 2026
da88b09
Merge main (sponsor line) into dev
fylorn Oct 2, 2026
1a399e7
Allow clippy::double_must_use on the async_trait BlobStore (#73)
fylorn Oct 2, 2026
8d8d96f
Unify the request guards with thinkwatch-core's rule model (#72)
fylorn Oct 3, 2026
2baa123
Fix what the pre-release review of the guard unification found (#75)
fylorn Oct 3, 2026
33c22dc
Merge main (v3.0.0) into dev
fylorn Oct 3, 2026
dcc8616
Merge main (README: ThinkWatch Lite for individual developers) into dev
fylorn Oct 4, 2026
f221d87
chore(release): tag 3.1.0
fylorn Oct 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 40 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,44 @@ target.

## [Unreleased]

## [3.1.0] — 2026-10-05

The thinkwatch-core crates move from v0.59.0 to v0.62.0. Two changes reach
the gateway: tool-call inspection gains a built-in rule for ThinkWatch's own
data directory, and an upstream whose base URL already ends in an API
version is no longer sent a second one.

### Read before upgrading

- The new tool-call rule `thinkwatch-data` is on and set to cut off, like
the other high-risk built-in rules. A deployment whose tool-call
inspection is in enforce mode starts cutting off answers whose tool call
reads or changes one of the paths below; one in observe mode only records
them. Set the rule to record, or switch it off, on the security page to
keep the previous behaviour.

### Added

- **Tool-call inspection: `thinkwatch-data` (Read or change ThinkWatch's own
data).** A tool call whose path or command points into ThinkWatch's data
directory (`~/.thinkwatch`, `%APPDATA%\ThinkWatch`, `/var/lib/thinkwatch`,
`/etc/thinkwatch`) — where the desktop gateway keeps every upstream key and
its own protection settings. Text that only mentions the directory, such as
a document being edited, does not count. The security page lists it with
the other built-in rules.

### Fixed

- **Upstream base URLs that end in their own API version** (`…/api/paas/v4`,
`…/api/v3`) now receive requests under that version instead of a second
`/v1` appended to it, which returned 404. Requests and connection tests
both use it.

### Changed

- thinkwatch-core crates (tw-bedrock, tw-breaker, tw-dialect, tw-guard)
v0.59.0 → v0.62.0.

## [3.0.0] — 2026-10-03

The request guards — outbound redaction, tool-call inspection and the
Expand Down Expand Up @@ -1142,7 +1180,8 @@ unreleased builds should: stop the gateway, run `db/schema.sql`
against PostgreSQL, restart against this tag. The schema is
idempotent end-to-end, so the apply is safe to repeat.

[Unreleased]: https://github.com/ThinkWatchProject/ThinkWatch/compare/v3.0.0...HEAD
[Unreleased]: https://github.com/ThinkWatchProject/ThinkWatch/compare/v3.1.0...HEAD
[3.1.0]: https://github.com/ThinkWatchProject/ThinkWatch/releases/tag/v3.1.0
[3.0.0]: https://github.com/ThinkWatchProject/ThinkWatch/releases/tag/v3.0.0
[2.2.0]: https://github.com/ThinkWatchProject/ThinkWatch/releases/tag/v2.2.0
[2.1.0]: https://github.com/ThinkWatchProject/ThinkWatch/releases/tag/v2.1.0
Expand Down
36 changes: 18 additions & 18 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ members = [
]

[workspace.package]
version = "3.0.0"
version = "3.1.0"
edition = "2024"
# Pin the MSRV to the first stable rustc that ships edition 2024 (1.85,
# released 2025-02-20). Without this, contributors on older toolchains
Expand Down Expand Up @@ -70,10 +70,10 @@ opt-level = 3
# never re-exported through a local shim. And the reverse: something only
# this side uses (the at-rest crypto, IMDSv2 credentials, the gateway error)
# lives here, not in core.
tw-bedrock = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.59.0" }
tw-breaker = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.59.0" }
tw-dialect = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.59.0" }
tw-guard = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.59.0" }
tw-bedrock = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.62.0" }
tw-breaker = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.62.0" }
tw-dialect = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.62.0" }
tw-guard = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.62.0" }

# Web framework
axum = { version = "0.8", features = ["macros", "ws"] }
Expand Down
4 changes: 2 additions & 2 deletions deploy/helm/think-watch/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ apiVersion: v2
name: think-watch
description: Enterprise AI API Gateway & MCP Management Platform
type: application
version: 3.0.0
appVersion: "3.0.0"
version: 3.1.0
appVersion: "3.1.0"
keywords:
- ai
- gateway
Expand Down
2 changes: 1 addition & 1 deletion web/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "web",
"private": true,
"version": "3.0.0",
"version": "3.1.0",
"type": "module",
"packageManager": "pnpm@11.0.0",
"scripts": {
Expand Down
4 changes: 2 additions & 2 deletions web/scripts/check-i18n.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const REDACT_RULE_IDS = [
const TOOL_RULE_IDS = [
'curl-pipe-sh', 'base64-decode-exec', 'exfil-env', 'exfil-credentials',
'exfil-credentials-reversed', 'ssh-key-read', 'secret-to-unknown-host',
'write-startup-item', 'crontab-install', 'rm-rf-root', 'chmod-777',
'thinkwatch-data', 'write-startup-item', 'crontab-install', 'rm-rf-root', 'chmod-777',
'upload-file-to-host',
];
const INVISIBLE_RULE_IDS = ['unicode-tags', 'bidi-controls', 'zero-width', 'private-use'];
Expand Down Expand Up @@ -87,7 +87,7 @@ const DYNAMIC_ENUMS = {
'contentSecurity.contentWhy.${_}': INVISIBLE_RULE_IDS,
'contentSecurity.cardNetwork.${_}': ['UnionPay'],
// Tool-call checks implemented in code (`{ kind: 'builtin', check }`).
'contentSecurity.check.${_}': ['credential-to-network', 'file-to-network'],
'contentSecurity.check.${_}': ['credential-to-network', 'file-to-network', 'thinkwatch-data'],
'contentSecurity.dialog.match.${_}': ['contains', 'regex', 'codepoints'],
'contentSecurity.dialog.regexHint.${_}': GUARD_IDS,
'contentSecurity.dialog.actionWhat.${_}': ['cut', 'block', 'strip'],
Expand Down
5 changes: 5 additions & 0 deletions web/src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@
},
"check": {
"credential-to-network": "A credential sent to a host other than this machine and the credential's own provider",
"thinkwatch-data": "A path or command that points into ThinkWatch's data directory; a mention does not count",
"file-to-network": "A local file uploaded to an external host"
},
"cardNetwork": {
Expand Down Expand Up @@ -400,6 +401,10 @@
"name": "Send a credential to an unknown host",
"why": "Sends a credential to a host that is neither local nor the credential's own provider"
},
"thinkwatch-data": {
"name": "Read or change ThinkWatch's own data",
"why": "Reads or changes ThinkWatch's data directory, which holds every upstream key in plain text and the settings of these protections"
},
"write-startup-item": {
"name": "Write a startup item",
"why": "Writes somewhere that runs at login or whenever a terminal opens"
Expand Down
5 changes: 5 additions & 0 deletions web/src/i18n/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@
},
"check": {
"credential-to-network": "凭据发往本机和其服务商以外的主机",
"thinkwatch-data": "路径或命令指向 ThinkWatch 的数据目录;只是提到不算",
"file-to-network": "本地文件上传到外部主机"
},
"cardNetwork": {
Expand Down Expand Up @@ -400,6 +401,10 @@
"name": "发送凭据到陌生主机",
"why": "将凭据发送到本机和该凭据所属服务商以外的主机"
},
"thinkwatch-data": {
"name": "读写 ThinkWatch 自己的数据",
"why": "读写 ThinkWatch 的数据目录,其中以明文保存全部上游密钥和这几项防护的设置"
},
"write-startup-item": {
"name": "写入启动项",
"why": "写入开机或打开终端时自动执行的位置"
Expand Down
Loading