60 Commits
Author SHA1 Message Date
rays f38a0921b3 fix(diagnostics): respect optional core branch inputs 2026-10-25 17:13:21 +08:00
rays 60ea66c3ec fix(diagnostics): preserve opaque node identities and exact targets 2026-10-25 16:33:06 +08:00
rays a23ecd2801 fix(stats): compute node health from the history entries actually stored
Node-health statistics read node_info and error_type, but stored
history entries carry node_context and pattern metadata instead, so
node_health was always empty outside of tests. The node class now comes
from node_context (node_class, then node_name), with the old node_info
shape still accepted, and counts stay weighted by repeat_count.

The last_error label is the matched pattern id or category ("unknown"
otherwise); raw error text, paths and node ids never enter the
statistics payload.
2026-10-13 14:33:47 +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 b4ce814d28 fix(chat): apply the configured token budget to chat requests
The chat route built its estimator settings with a keyword the settings
type does not have, so every budgeted chat raised a TypeError that the
fail-open handler logged and ignored; the token budget never trimmed a
chat request. The settings now use the correct field, the budget service
estimates with the per-request estimator settings instead of always
using its construction-time estimator, and a skipped budget is logged
with a stable code and the exception type only.

Oversized contexts are now trimmed along the configured ladder before
the prompt is built, budget metadata is returned for streaming and
non-streaming chat, and the existing remote/local switches still turn
the budget off.
2026-10-13 13:48:27 +08:00
rays 90827a8e6c fix(security): bind server-held LLM keys to their approved destinations
Server-held credentials were chosen from the caller's provider hint, so an
approved destination could receive another provider's key, local services
received provider keys, and connectivity-only gateways received the generic
key. Release is now decided from the matched destination only:

- official providers get their own key, then the generic key;
- the DOCTOR_LLM_BASE_URL endpoint gets the generic key only;
- DOCTOR_LLM_ALLOWED_BASE_URLS endpoints and local services get none;
- request keys are unchanged, and a hint cannot make an official
  provider keyless.

Provider detection uses exact hosts instead of substring matching.
2026-10-13 13:02:58 +08:00
rays 48abb93869 fix(security): harden LLM destination checks after review
- Let an inherited proxy on an unregistered host:port (e.g. localhost:7890)
  through the connect-time resolver; registered host:port pairs stay checked.
- Accept underscores inside host labels so Docker service names such as
  my_ollama can be approved.
- Refuse IPv4-compatible and site-local IPv6 for official providers and
  judge NAT64/6to4/compatible forms by the IPv4 address they carry.
- Fix approved destinations when routes are registered instead of on the
  first request.
- Static outbound check: exact path matching, import-alias and
  TCPConnector detection, policy factory wiring, raw HTTP client imports,
  no nosec for policy rules, fail closed on unparseable files.
- Settings: restore the model controls when the base URL is empty.
2026-10-13 12:47:35 +08:00
rays e430a51c80 fix(security): keep the destination policy importable on aiohttp 3.9
ResolveResult only exists in aiohttp 3.10+, but the node uses the
host-bundled aiohttp. Import it for type checking only so hosts that still
ship aiohttp 3.9 load the node and keep the connect-time destination check.
2026-10-13 12:28:15 +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 a951b03b9a fix(compat): align host contracts and node focus lifecycle
Refresh exact frontend lanes and relocated host contracts while preserving
Desktop settings behavior. Recognize first-party Switch nodes and optional
branches without suppressing required-input or broken-link diagnostics.

Revalidate canvas, workflow and target identity across focus navigation;
cancel stale requests on newer actions and sidebar teardown. Keep legacy
positioning and nested graph traversal covered by action-level regressions.

Validation: 75 source contracts, 84 frontend unit tests, Windows full gate
with 871 backend tests and 125 subtests, and 149 mocked browser E2E tests.
Seven existing backend skips remain. No live-host certification is claimed.
2026-09-22 15:18:41 +08:00
rays f5c2355e36 fix(diagnostics): stop warning for optional xformers
Treat xFormers absence as a valid host configuration while preserving capability discovery, runtime-error context, and Triton diagnostics.
2026-09-19 18:06:10 +08:00
rays b983a746fb fix(diagnostics): resolve SAM3D assets from detection 2026-09-04 22:21:52 +08:00
rays 4288961706 fix(diagnostics): accept current dynamic vram warning 2026-09-04 22:09:27 +08:00
rays cce05160da feat(diagnostics): surface DynamicVRAM fallback advisory 2026-08-19 16:48:22 +08:00
rays e24da07571 fix(diagnostics): align promoted media asset detection 2026-08-08 16:48:48 +08:00
rays b16c5f8af6 fix(diagnostics): align pytorch minimum with host 2026-08-08 16:26:47 +08:00
rays 9524e7e20f feat(diagnostics): validate first-party dataset folders 2026-07-31 04:18:48 +08:00
rays 702e5ebd56 fix(diagnostics): support named workflow widget values 2026-07-31 04:06:41 +08:00
rays 0afae045ac fix(paths): separate desktop identity from storage 2026-07-19 20:13:04 +08:00
rays 63dabddd49 feat(diagnostics): scan registered nested model assets 2026-07-19 19:42:39 +08:00
rays cc4246c293 fix(diagnostics): align Python and Torch support 2026-07-19 19:23:40 +08:00
rays 912a4280d2 fix(security): redact sensitive headers unconditionally 2026-07-19 18:54:16 +08:00
rays ff2c8bca8d fix(diagnostics): contain model asset paths 2026-07-19 18:36:21 +08:00
rays 797a736aa5 fix(diagnostics): align model asset loader categories 2026-06-24 17:18:48 +08:00
rays b0feb1bb73 fix(diagnostics): align model asset folders 2026-06-12 16:02:35 +08:00
rays 302cdae6af refactor(services): add domain entry points 2026-05-31 13:34:40 +08:00
rays 18ae26f61d refactor(api): decompose route registration 2026-05-31 12:57:39 +08:00
rays 534949c17d fix(diagnostics): align model asset folders 2026-05-31 12:02:34 +08:00
rays def6bfd229 fix(security): use private host state directory 2026-05-13 15:45:38 +08:00
rays e659683562 feat(llm): add provider adapter contract 2026-04-26 19:39:21 +08:00
rays 693ee4ebb6 fix(diagnostics): remove placeholder health check 2026-04-26 19:13:42 +08:00
rays 63b7770c27 fix(imports): guard absolute fallback paths 2026-04-26 19:04:24 +08:00
rays 7906b661f0 fix(api): standardize error response envelopes 2026-04-26 18:45:51 +08:00
rays d6a6240b69 docs(security): describe secret store crypto metadata 2026-04-25 17:59:17 +08:00
rays b43ce5ba41 fix(security): require admin token in strict mode 2026-04-25 17:54:17 +08:00
rays 8f99daa282 fix(imports): harden package-safe startup loading 2026-04-04 16:27:47 +08:00
rays d34ccbfd61 fix(paths): prefer portable custom_nodes root over repo venv heuristic 2026-03-26 20:43:40 +08:00
rays 2d4ce9c0ad feat(r21): standardize runtime utc-aware timestamps 2026-03-26 19:20:58 +08:00
rays 16ea282cda feat(r24): verify desktop virtualenv path compatibility 2026-03-26 19:11:50 +08:00
rays cd19630539 feat(r23): align execution_error compatibility with subgraph workflows 2026-03-26 18:58:24 +08:00
rays deb5dd99ab feat(security): harden server secret store with optional encryption 2026-02-27 14:52:55 +08:00
rays cfd9bec7f9 feat(security): enforce S10 admin guards on write routes 2026-02-27 14:32:56 +08:00
rays aadecde72f feat: add F18 diagnostics signature packs 2026-02-27 01:55:41 +08:00
rays 633603d785 feat: add F16 quick feedback PR flow 2026-02-27 01:42:31 +08:00
rays f45656d27d feat: complete validation expansion with guardrail wiring, desktop failure-injection tests, isolation coverage, and opt-in online API lane 2026-02-17 03:51:43 +08:00
rays aaa45ce319 feat: add env-driven runtime guardrails with runtime-only config persistence and R17 regression coverage 2026-02-17 02:22:51 +08:00
rays 3612975c89 feat: add fail-closed external enrichment foundation, resumable job APIs, and non-stream LLM output cleanup 2026-02-17 01:52:32 +08:00
rays 0456823e93 feat: finalize dual-mode API key strategy (ENV-first + advanced server key store) 2026-02-10 15:43:06 +08:00
rays 11f56bc7f3 feat(r18): store diagnostics history under canonical Doctor data dir 2026-01-23 22:27:33 +08:00