8 Commits
Author SHA1 Message Date
rays 8d33acac4a chore(release): prepare 2.1.0 documentation and metadata 2026-10-25 19:31:50 +08:00
rays 88755379b0 chore(release): bump version to 2.0.5 2026-10-13 15:26:40 +08:00
rays 3c73c29d75 fix: realign diagnostics, telemetry and metadata contracts with their producers
- Privacy diagnostics: the provider name is None for unknown endpoints
  and when no base URL is set; calling .lower() on it raised and dropped
  every issue of the check, including the warning for privacy_mode=none
  with an unknown remote endpoint.
- Telemetry: the pattern allowlist built a PatternLoader without its
  required directories, so it was always empty and every pattern label
  became __unknown__. It now reads ids from the shared loader through a
  new PatternLoader.get_pattern_ids().
- Error summary: the LLM context builder read the category from a nested
  pattern_match key that the pattern stage never writes; it now reads the
  top-level category (nested key kept as a fallback).
- Sidebar: an error delivered before the sidebar panel existed (it waits
  for UI text) threw on auto-open, and so did the menu toggle. Visibility
  is now applied when the panel is created.
- OpenAPI info.version now matches the package version, and the version
  metadata test enforces it.
- A missing optional patterns/custom directory is logged at debug level
  instead of a warning; missing built-in directories still warn.
2026-10-13 14:28:45 +08:00
rays 8c5f2354cf fix(security): keep an unreadable encrypted secret store locked instead of replacing it
An encrypted server-side credential store that could not be opened was
destroyed on the next access: with the encryption key missing, the next
save rewrote it as plaintext; with a different key, the failed MAC check
renamed it aside as corrupt and a new store was started under the new key.

The store now classifies its state as ok, empty, locked_key_required,
locked_key_mismatch or corrupt. A locked store is never rewritten,
downgraded or moved: reads return nothing, writes raise
SecretStoreLockedError, and the locked state is logged once per change
without key material. Only structurally unreadable files are still
rotated aside.

GET /doctor/secrets/status reports store.state, and PUT /doctor/secrets
and DELETE /doctor/secrets/{provider} return HTTP 409 with error code
secret_store_locked. The OpenAPI contract and the configuration security
guide document the states and the recovery steps.
2026-10-13 14:04:53 +08:00
rays cc31b1433d fix(security): restrict LLM requests to operator-approved destinations
The analyze, chat, verify-key and model-list routes sent server-side
requests to a caller-supplied base URL guarded only by a pre-flight
denylist. Callers could choose arbitrary hosts and paths, reach shared
address space and metadata ranges, drive local LLM write APIs, and use
DNS rebinding to deliver server-held keys to loopback services.

Requests now select an entry of an immutable destination registry built
at startup from the built-in provider catalog, local Ollama/LM Studio,
and operator environment variables (DOCTOR_LLM_ALLOWED_BASE_URLS and the
existing base URL variables). Outbound URLs are built from the approved
entry, resolved addresses are checked at connect time inside the shared
connector, redirects are never followed or treated as success, and error
responses no longer reflect upstream bodies or network details. The UI
shows localized operator guidance, a static rule enforces disabled
redirects and policy-managed sessions, and .comfyignore keeps tests and
tooling out of the published archive.
2026-10-13 12:22:39 +08:00
rays f3230ac401 docs: document current host and health updates 2026-08-19 17:30:29 +08:00
rays 1335efa5e7 docs(api): document host route aliases 2026-06-12 16:24:31 +08:00
rays 6b2403f4f5 docs(api): add openapi contract 2026-05-31 13:47:39 +08:00