195 lines
11 KiB
Markdown
195 lines
11 KiB
Markdown
# Current Architecture Decisions
|
|
|
|
This index records concise reasons for enduring product and architecture
|
|
boundaries. It is not a changelog. When a decision becomes obsolete, update or
|
|
replace the record and rely on Git history for the former implementation.
|
|
|
|
## AD-001 — One command, exclusive browser entries
|
|
|
|
The floating trigger, action-bar button, and Extensions command share one
|
|
`openBrowser()` command and one browser instance. Presentations are mutually
|
|
exclusive, while the Extensions command always remains as a recovery route.
|
|
Native ComfyUI command/keybinding infrastructure owns shortcut recording and
|
|
modal guards.
|
|
|
|
## AD-002 — Recipes are templates; notebooks are immutable instances
|
|
|
|
A Workflow Recipe is the authoritative workflow template. Parameter Notebooks
|
|
are immutable generation-value snapshots attached to a recipe and browsed inside
|
|
its Parameters tab. The Node Assistant may reuse those snapshots for a selected
|
|
same-type node, but this does not replace full-skeleton recipe application.
|
|
|
|
## AD-003 — Recipe canvas actions follow graph scope
|
|
|
|
Recipe cards and detail views append partial recipes because their open required
|
|
connections make them composition fragments. Complete, independently runnable
|
|
recipes load through ComfyUI's workflow path and therefore open as a new canvas
|
|
in the current frontend. Structural editing remains a separate, explicitly
|
|
confirmed workflow.
|
|
|
|
## AD-004 — Recipe save hides implementation policy
|
|
|
|
Save collects identity, notes, tags, and cover/source image. Presentation pins
|
|
and snapshot policy are implementation choices, not per-save questions. Legacy
|
|
pin data is preserved without exposing a control; new recipes default to none.
|
|
|
|
## AD-005 — Model identity excludes names and previews
|
|
|
|
Model Doctor automatically proves identity through provenance hash and required
|
|
category; byte size may disambiguate that hash. A unique size-only match is a
|
|
manual candidate, never proof or an automatic redirect. Hash/size conflicts are
|
|
rejected. Local paths, filenames, display names, previews, and similarity are
|
|
presentation or post-resolution routing data. This boundary prevents silent
|
|
substitution after local rename or across categories.
|
|
|
|
## AD-006 — Foundation components are hash-only recovery categories
|
|
|
|
VAE, VAE Approx, CLIP/Text Encoder, and CLIP Vision files can commonly share
|
|
sizes or ambiguous names. Automated redirection therefore requires one exact
|
|
in-category hash match. A size-only candidate may still be shown for explicit,
|
|
one-time confirmation on the current node. Existing native combo values remain
|
|
usable with a visible identity-change warning when provenance differs. This does
|
|
not restrict scan coverage: scanning may calculate hashes for any active
|
|
registered folder, including categories whose Civitai metadata coverage is weak.
|
|
|
|
## AD-007 — Recipe origins and local availability are separate
|
|
|
|
Official origin metadata can be refreshed or edited independently of saved
|
|
identity. Exact-path availability checks and previews describe the current
|
|
machine; they do not rewrite imported provenance or activate a local match.
|
|
|
|
## AD-008 — Prompt roles prefer unknown over a guess
|
|
|
|
Automatic prompt role tracing follows only allowlisted native prompt,
|
|
conditioning, and consumer nodes. Unknown third-party nodes are opaque. Legacy
|
|
full-value recovery must be exact and unambiguous, and users may store explicit
|
|
recipe-scoped overrides.
|
|
|
|
## AD-009 — Recipe-to-model navigation is recoverable and exclusive
|
|
|
|
Model detail temporarily replaces all main content surfaces while retaining a
|
|
small recipe return token. Back reconstructs recipe detail; unrelated navigation
|
|
abandons the token and cleans stale state. The transition never closes the outer
|
|
browser or exposes model detail beside Node Assistant.
|
|
|
|
## AD-010 — Parameter selection must identify both panes
|
|
|
|
The active Parameter Notebook is visible in the list and in a right-pane banner
|
|
with name and timestamp. Requests are selection-tokened so stale gallery results
|
|
cannot overwrite the new notebook. Sidebar input/button rows must remain usable
|
|
in the narrow docked layout.
|
|
|
|
## AD-011 — Output discovery remains bounded and user-refreshed
|
|
|
|
Recipe matching inspects at most the newest bounded set of PNG metadata and has
|
|
no persistent index. The main Gallery scans on open and refreshes manually. This
|
|
avoids background polling and hidden indexing cost while retaining predictable
|
|
freshness.
|
|
|
|
## AD-012 — Licensing and branding are separate
|
|
|
|
The standard MIT `LICENSE` applies to project-owned code and documentation.
|
|
`TRADEMARKS.md` separately governs the Anomalous Model Browser name and official
|
|
branding. Project-specific restrictions are not appended to the MIT license.
|
|
|
|
## AD-013 — Beta guidance is scoped to experimental workflow features
|
|
|
|
Workflow Recipes and recipe-powered Assistant presets carry localized backup and
|
|
data-safety guidance until an explicit stability decision removes it. Stable
|
|
Node Assistant model replacement and LoRA insertion are outside that warning.
|
|
Notices distinguish single-node preset application from full-skeleton Parameter
|
|
Notebook application.
|
|
|
|
Status (2026-10-09): ended with v1.60.0, the first release not marked beta. The
|
|
in-app beta notices had already been removed.
|
|
|
|
## AD-014 — Architecture documentation is state, not history
|
|
|
|
Architecture documents change only when an owner, data flow, interface contract,
|
|
persistence format, security boundary, or critical invariant changes. Ordinary
|
|
fixes do not append “unchanged” entries. Git is the implementation history;
|
|
`CHANGELOG.md` is user-facing release history; `docs/architecture/lessons.md` holds
|
|
only durable recurring traps.
|
|
|
|
## AD-015 — Recipe model mutations update all identity representations
|
|
|
|
The authoritative workflow widget, structured model reference, and node-scoped
|
|
Model Doctor Hash index form one mutation boundary. Local matching updates all
|
|
three through the archived full-recipe path. Partial append remaps Hash records
|
|
with node IDs and rolls them back with the inserted graph. Personal model notes
|
|
are recipe-scoped presentation data and may be excluded from package export.
|
|
|
|
## AD-016 — The audio page manages one speech engine
|
|
|
|
The audio page is built around GPT-SoVITS through the separate Anomalous_TTS
|
|
node pack: its characters, emotions, pronunciation and sampling defaults live in
|
|
the node's own settings, and the Script Director can run a script without the
|
|
canvas. The F5-TTS voice library (files under `input/F5-TTS`, upload, romanization,
|
|
Load Audio drags) was removed rather than kept as a parallel engine, so the page
|
|
teaches one set of rules. A zero-shot voice (one clip, no trained model) belongs
|
|
in Anomalous_TTS as a character kind, not as a second engine here.
|
|
|
|
## AD-017 — The browser is a rail of pages with a home page
|
|
|
|
Navigation is one narrow icon rail: a home page, the image pages (models, gallery,
|
|
workflows, materials), the audio pages (voices, audio gallery), the canvas tools and
|
|
settings. The rail replaces the header tabs, the image/audio toggle and the tool bar
|
|
under the folder list, so the list column holds only a list and can close without
|
|
hiding any command. Each page decides whether it has a list; the open state is
|
|
remembered per page and narrow windows start with it closed. The home page offers
|
|
tasks rather than a manual: each card opens its page, and a first visit lands there.
|
|
AMB stays the chore layer around ComfyUI (AD-016 keeps one engine per page); a new
|
|
page earns a rail entry only when it is a place users return to, not a one-off tool.
|
|
|
|
## AD-018 — The activity log records what Anomalous changed, without undo for now
|
|
|
|
Users need to see what the plugin did to their canvas and files. File changes are
|
|
recorded on the server, after a write request succeeds, from one table of routes,
|
|
so a new write route is logged by adding a line there. Canvas changes are recorded
|
|
without each action reporting itself: a press inside Anomalous takes a snapshot, and
|
|
the difference is logged when the user next presses or types outside it, so the
|
|
user's own edits are never attributed to the plugin. Opening another workflow is
|
|
logged as that, not as removed nodes. The log is bounded and never fails the action
|
|
it records. Undo comes later and only for changes that can be reversed safely
|
|
(canvas values, renames); deletions go through their own confirmations instead.
|
|
|
|
## AD-019 — No Civitai browser inside Anomalous; imported files are put in place
|
|
|
|
New users' trouble is not finding models but knowing which folder a downloaded file goes
|
|
in. A Civitai browser inside the plugin would not reach many users (Civitai is often
|
|
unreachable from mainland China, where most models come from LiblibAI, cloud drives and
|
|
chat groups), would mirror a large site's search, filters and content rating, and would
|
|
show its picture feed inside the plugin. Instead the plugin takes a file from wherever it
|
|
came from: dropped on the models page, it is told apart by its header (never by running
|
|
it), checked against Civitai when that answers, and moved into the folder its type and
|
|
base model call for, with every guess shown and changeable before anything moves.
|
|
|
|
## AD-020 — Downloads extend Model Check's evidence rules; ComfyUI-Manager is a catalog
|
|
|
|
A missing model is downloaded only from a source that names one file, asked in turn:
|
|
Civitai by the workflow's hash, a link the workflow carries, then ComfyUI-Manager's model
|
|
list by file name. The list carries no hashes: it answers where a file of that name can be
|
|
fetched, never whether a local file is that model, so it is never evidence for local
|
|
recovery (AD-005). With the workflow's hash every source must show the same SHA-256 (read
|
|
from the host, Hugging Face's headers) before the file counts; a different one is refused.
|
|
Without a hash nothing can be checked before or after the download, so a name is at most
|
|
"maybe": one list entry of that name and of the node's type is offered as "Download by
|
|
name", marked as such, never in Download all nor the MCP's downloads. Foundation components
|
|
(AD-006) follow one rule: a name alone only ever proposes, and their same-name candidate
|
|
needs a second, independent piece of evidence: the same size for a local file, the
|
|
curated list's entry of the right type for a download; the user still presses. Where no
|
|
source answers, the plugin opens a search (Hugging Face) for the user rather than pick a
|
|
file of a common name itself. The full rules in plain words are in
|
|
`docs/guides/model-check-rules.md`.
|
|
|
|
## AD-021 — A combo remembers; it never changes a value
|
|
|
|
A combo puts back exactly what was saved: models, LoRA strengths, CLIP skip, prompts and
|
|
every other value of its nodes, never node defaults in their place and never values the
|
|
plugin chose. A different value is a different combo, made by setting it on the canvas
|
|
and saving again. A picture kept as a combo therefore keeps the nodes that made its
|
|
sampler's model and prompts as a node structure, values untouched (a workflow without a
|
|
sampler falls back to the older main model, LoRAs and positive prompt). Placing a combo
|
|
only adds a new group; nodes already on the canvas are never changed (their values are
|
|
changed in Current node). This is one of the feature principles in AGENTS.md.
|