Skip to content

Commit 0642fe9

Browse files
authored
release: v3.11.0
See CHANGELOG.md [3.11.0].
1 parent 07bb13d commit 0642fe9

93 files changed

Lines changed: 6264 additions & 1064 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎CHANGELOG.md‎

Lines changed: 164 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,168 @@ target.
1111

1212
## [Unreleased]
1313

14+
## [3.11.0] — 2026-11-03
15+
16+
Execution and buffering now adapt automatically to available CPUs and memory,
17+
including container limits. CPU work expands with traffic and extra threads
18+
retire after ten idle seconds; no runtime configuration change is required.
19+
20+
Secrets and privacy recognises far more: the built-in redaction catalog
21+
grows from 30 rules to 131 in 20 groups, and the API keys saved
22+
for the providers are recognised by value, whatever their format. The
23+
console shows the rules' names and descriptions as thinkwatch-core
24+
writes them, in both languages. A value recognised by mistake can be made
25+
an exception without switching its rule off, and long conversations are
26+
no longer scanned from the start every turn. A provider can set the
27+
slowest generation its streams may keep up, and a stream that falls
28+
below it is cut so the client can try again. The thinkwatch-core crates
29+
move from v0.83.1 to v0.89.0.
30+
31+
No new runtime setting. Two new provider columns
32+
(`providers.min_speed_tokens_per_sec`, `providers.min_speed_window_secs`,
33+
added on startup). New metrics cover minimum generation speed, buffering
34+
pressure and audit backlog memory.
35+
The redaction policy gains one optional field (`exceptions`), with
36+
endpoints of its own under `/api/admin/security/redact/exceptions`.
37+
38+
### Read before upgrading
39+
40+
- **Buffering is admitted against a process-wide memory budget.** Request,
41+
response, cache and retained streaming data use limits derived from the
42+
container or machine's memory. Temporary pressure returns a retryable 429
43+
with `Retry-After: 1`; an already-started stream receives an error event.
44+
Large upstream responses and stream timelines are bounded, and new audit
45+
entries are dropped with metrics if the separate audit byte budget fills.
46+
See [automatic process resources](docs/operations/resources.md) for the
47+
limits and monitoring. These allocation budgets are not a hard RSS cap.
48+
- **UUIDs and blockchain credentials gain built-in rules.** Core v0.88.0
49+
added 11 rules, enabled by default, including UUIDs, wallet keys and
50+
accounts, exchange credentials and recovery material. Monitor records
51+
findings; installations with protection On replace matching message
52+
text. UUIDs, hashes and public accounts do not independently trigger
53+
credential-exfiltration blocking. Review any workflows that send order
54+
or trace identifiers as message text.
55+
- **New credential rules ship on.** Under the On state of Secrets and
56+
privacy (`security.redact` mode `enforce`), values they find start
57+
being replaced with placeholders: among them credentials in request
58+
headers, command lines, URLs and bot webhooks, and secrets assigned in
59+
`.env`-style configuration (`DB_PASSWORD=…`). Under Monitor, the
60+
factory state, they are only recorded. A rule that gets in the way can
61+
be switched off on its own in the console.
62+
- **Some keys are reported under a rule of their own.** `sk-or-v1-`
63+
(OpenRouter), `sk-lf-` (Langfuse), `sk-svcacct-`, `sk-admin-` and
64+
`sk-api-` keys were reported as `openai-api-key`; they now have their
65+
own rule ids, and so do audit events and the
66+
`gateway_redaction_found_total` metric's `kind` label, which follows
67+
the new groups (`ai-services`, `dev-platforms`, `cloud`, …) instead of
68+
`api-keys` and `personal`.
69+
70+
### Added
71+
72+
- **Expanded redaction rules** (thinkwatch-core v0.85.0 and later): about 50 more
73+
prefixed credentials (AI services, code hosting, cloud, payments and
74+
collaboration), credentials by position (request headers, command
75+
lines, URL parameters, bot webhooks, configuration assignments),
76+
cryptocurrency recovery phrases and private keys, and personal
77+
information: identity documents, foreign ID numbers, IBAN, phone
78+
numbers, addresses and coordinates, vehicles, device identifiers and
79+
values by field name. Of the new personal-information rules only the
80+
two that can be checked digit by digit ship on (passport
81+
machine-readable zone, IBAN), alongside the resident ID and bank card
82+
numbers as before.
83+
- **Saved upstream keys are recognised by value.** The API keys in each
84+
provider's credential headers (the `Bearer` scheme left out) and a
85+
Bedrock provider's secret access key are matched wherever they appear
86+
in a request, as written or JSON-escaped; values shorter than 12
87+
characters are not. The list follows the providers: it is rebuilt when
88+
they load, when one is created, changed or deleted, and on the other
89+
instances through the router reload. The same keys count as
90+
credentials for the dangerous-commands rule "credential sent to an
91+
unknown host", each allowed to its own provider's host, and the
92+
console's trial recognises them too.
93+
- **A saved key's audit event names its provider, never the value.** The
94+
`gateway.redaction_*` event of the rule `thinkwatch-saved-secret`
95+
carries `sources` (`[{"kind": "upstream-key", "name": <provider>}]`)
96+
and no masked values; the security log shows it as the provider's API
97+
key.
98+
99+
- **Exception values** (`security.redact.exceptions`, the Exceptions
100+
section under the Secrets and privacy rules). A value listed there is
101+
neither replaced nor recorded, whichever rule finds it; the rules keep
102+
working for every other value. A value is added by pasting it: the
103+
server hashes it on arrival and keeps only its SHA-256, its masked form,
104+
the rule that recognised it and when it was added, never the value. At
105+
most 500; at the cap, adding is unavailable. Saved provider keys cannot
106+
be exceptions. Listing them takes `settings:read`; adding and removing
107+
take `settings:write` and `pii_redactor:write`, and each is written to
108+
the audit log (`security.redact_exception_added`,
109+
`security.redact_exception_removed`) with the rule and the masked value
110+
only. The trial marks an excepted value as left as is.
111+
- **Unchanged conversation history is not scanned again.** Each gateway
112+
instance keeps, in memory, where the redaction rules matched in the
113+
parts of recent requests it has scanned (positions and rule ids, never
114+
values); the next turn of the same conversation takes those parts from
115+
it and scans only what is new. What is found is the same as without it.
116+
The cache is rebuilt whenever the rules, the providers' keys or the
117+
exceptions change.
118+
- **Stop a stream that generates too slowly** (the provider's
119+
"Stop when generation is slower than … tokens/s for … s" setting,
120+
`min_speed_tokens_per_sec` 1–1000 and `min_speed_window_secs` 5–120,
121+
default 20, on the provider endpoints; blank or `null` is off, the
122+
default). From the first token on, a stream is judged once a second:
123+
when the visible text it streamed over the last window (answer,
124+
reasoning streamed as generated, and tool arguments; four ASCII
125+
characters or one other character to a token) comes to fewer tokens
126+
per second than the minimum, the stream ends with a 503 error in the
127+
client's format (`overloaded_error` for Anthropic, `response.failed`
128+
for Responses, `UNAVAILABLE` for Gemini), the upstream connection is
129+
closed, and the route is charged a failure. Left out of the window:
130+
pauses of a quarter of the window or more (at most 5 s), and
131+
summarised reasoning (Responses reasoning summaries, Anthropic thinking
132+
blocks, Gemini thought parts, Bedrock reasoning content), which arrives
133+
in bursts while the model reasons; a window more than half left out is
134+
not judged. Nor is a second while summarised reasoning is open, one
135+
whose last content is more than a second old, or anything after the
136+
upstream has ended the answer. Counts the upstream reports are not
137+
used: Gemini's includes its hidden thoughts. The session's affinity to
138+
that route is dropped, the answer so far is billed as for any stream
139+
cut short, and the log row carries the error `UpstreamTooSlow` and the
140+
speed at the cut (`tokens_per_sec`). Whole answers and Responses
141+
WebSocket turns are not measured.
142+
143+
### Changed
144+
145+
- **CPU execution grows with load.** The permanent I/O scheduler uses at
146+
most eight workers by default. Parsing, redaction, inspection and
147+
conversion share CPU admission with password hashing; sufficiently
148+
provisioned 80-CPU machines can run 80 CPU jobs. Extra threads retire
149+
after ten idle seconds. Argon2 also observes a memory-based concurrency
150+
limit, retained until a running hash finishes even if its caller leaves.
151+
- **Buffers and audit retries retain admission until their final owner
152+
releases them.** Chunked AI/MCP responses, cache reads, transformed
153+
output and detached stream tails use the same buffering budget. MCP
154+
discovery, provider/registry catalogs, OAuth endpoints, S3 reads and
155+
audit-forwarder diagnostics also use bounded reads. Local pressure does
156+
not count as an upstream failure. Audit queue and ClickHouse retry
157+
batches share a separate byte limit and expose buffered-memory and
158+
dropped-entry pressure through metrics.
159+
- **Release binaries use mimalloc.** Linux also applies a process-local
160+
transparent-huge-page policy before runtime threads start. Host sysctls
161+
and deployment resource settings need no changes.
162+
- **A redaction policy written through `PATCH /api/admin/settings` keeps
163+
the stored exceptions**, whatever it carries: they are changed only
164+
through their own endpoints, and the console writes the rest of the
165+
policy back from the rule view, which does not carry them.
166+
- **Rule names and descriptions come from thinkwatch-core.** The security
167+
page shows each built-in rule's name, reason and description and each
168+
group's name as the rule view gives them, in English or Chinese; the
169+
console no longer keeps its own name tables. Security-log rows and
170+
trial hits name the rule by looking its id up in the rule view. The
171+
rule search also matches prefixes, field names and descriptions.
172+
- **The conversion of the old PII pattern list** switches on or off only
173+
the four personal-information rules that list could express; the new
174+
personal-information rules keep their factory setting.
175+
14176
## [3.10.0] — 2026-10-25
15177

16178
Upstreams that fail for the moment before any of the answer reached the
@@ -2694,7 +2856,8 @@ unreleased builds should: stop the gateway, run `db/schema.sql`
26942856
against PostgreSQL, restart against this tag. The schema is
26952857
idempotent end-to-end, so the apply is safe to repeat.
26962858

2697-
[Unreleased]: https://github.com/ThinkWatchProject/ThinkWatch/compare/v3.10.0...HEAD
2859+
[Unreleased]: https://github.com/ThinkWatchProject/ThinkWatch/compare/v3.11.0...HEAD
2860+
[3.11.0]: https://github.com/ThinkWatchProject/ThinkWatch/releases/tag/v3.11.0
26982861
[3.10.0]: https://github.com/ThinkWatchProject/ThinkWatch/releases/tag/v3.10.0
26992862
[3.9.1]: https://github.com/ThinkWatchProject/ThinkWatch/releases/tag/v3.9.1
27002863
[3.9.0]: https://github.com/ThinkWatchProject/ThinkWatch/releases/tag/v3.9.0

0 commit comments

Comments
 (0)