Part II — Settings and appearance
This part covers Chapters 6–10: an item-by-item lookup of the Settings panel, assistant-persona and model-provider fields, plus theme / appearance and system integration.
6. Settings panel
[!ref] Full details in the User Manual, "Global settings".
The Settings panel has 22 tabs organised into 6 groups. Listed below in UI order, with scope (G Global / W Workspace / M Mode) and defaults.
6.0 Settings panel groups
6 groups, each capped at 6 tabs, organised by mutually-exclusive domain × access frequency top-down:
| Group | Tabs | Purpose |
|---|---|---|
| Account | Account · Feedback | Sign-in / usage / points balance; feedback |
| General | General · Recent · Data · Routines | Theme, project workspace & session layout (sidebar / top tabs), message density, tray, auto-start, language, font, config directory, check for updates; recent workspaces; storage / backup / cleanup / sync; routines |
| Models | Providers · Model settings | LLM provider list / credentials / headers; default model, temperature, max tokens, timeout |
| Agent | Agents · Reflection · Skills · Tools · Hooks · Context · Memory palace | Personas for the five modes; Reflection page: restate intent / auto-reflect / auto-resume tasks; skill loading and signing; tool switches; pre-call confirmation and auto-approve; context and compaction; long-term memory |
| Security | Security · Skill/Plugin Signatures · Testing & checks · Data masking · Supply chain / SBOM | Hard guards; signing verification policy and trust store; self-check gate; outbound data masking; SBOM vulnerability-DB sources and offline sync |
| Extensions | Plugins · Messaging | Plugin marketplace / install / toggle / permissions; WeChat and other IM channels and binding codes |
6.1 Settings → Account
| Field | Scope | Default | Notes |
|---|---|---|---|
| Sign-in method | G | SMS code | SMS code (default; auto-register; 60s countdown; CAPTCHA on risk) / Username + password / SSO |
| Plan quota | G | Auto | Provisioned on sign-in; no manual config |
| Points-balance warning threshold | G | 1 hour | Sidebar dot turns amber within this window; panel uses § prefix |
| Usage windows | G | 24h / 7d / 30d | Refreshed every minute |
| Sign out | G | — | Click to execute; local data preserved |
| Redemption code | G | — | Enter and click "Redeem"; 12 localised outcomes |
| My Usage Coupons | G | — | All usage coupons: face value, expiry, "Permanent" tag where applicable |
| Available credits (source of truth) | G | — | Taken straight from the server's display field (/me.voucher_balance); the client never sums the coupon list itself, so the number always matches the web account page |
| Buy vouchers (account card) | G | — | Entry point on the account card (formerly "Quick buy"). The balance row is always rendered on a single line |
| Buy vouchers / Upgrade plan | G | — | The two buttons in the usage area and on the "Available points exhausted" banner |
| Purchase flow | G | — | First a tier dialog opens in the app ("Pick a tier, then confirm and pay in your browser"); after picking a tier the confirm-purchase page opens in the system browser: vouchers /quick-buy/?sku_id=<tier>&quantity=1; self-service plans /quick-buy/?plan_id=<plan>&months=1; "contact sales" plans → /dashboard/; "Open service page" at the bottom of the dialog → vouchers /recharge/, plans /dashboard/. Destinations follow the configured account-service base URL |
| Low-balance inline notice | G | Threshold < 50 | When signed in, the message was produced by AVL-Zero, the balance is known and strictly less than 50, the latest assistant message in this session shows "AVL Zero balance is down to §xx.xx and running low" + "Buy vouchers" / "Upgrade plan"; not repeated while streaming, when an out-of-credits red bar is already shown, or on older messages |
| Setup wizard | G | Opens automatically when no model is usable | Checked on every launch; three steps: Sign in → Create project ("Open project" when there is history) → Start chatting. Can be opened manually via "Setup wizard → Run setup wizard" at the bottom of the Account page, or "Run setup wizard" in the command palette |
6.2 Settings → General
| Field | Scope | Default | Notes |
|---|---|---|---|
| Language | G | Follow system | Listed under their own names: 简体中文 (Simplified Chinese) / 繁體中文 (Traditional Chinese) / English. Persisted as language; the header quick menu's "Language" slider syncs with this item |
| Theme | G | system | system / light / dark |
| Project workspace & session layout | G | Sidebar | sidebar (left sidebar) / tabs (top tab strip, content area edge-to-edge; open tabs persistently remembered, restored on restart; once signed in, the right end of the tab strip shows the current username, fixed width, ellipsised when too long). Persisted as workspace_display_mode; the header quick menu's "Layout" slider syncs with this item |
| Minimise to tray | G | Off | Closing window keeps app in tray |
| Auto-start at login | G | Off | Silent boot into tray |
| Font size | G | Medium | Small / Medium / Large |
| Message density | G | Normal | detailed (Normal, full cards / arg previews) / compact (Compact, no cards, slim rows + grouped process content). Field message_density; only compacts process rendering, body text untouched; legacy collapsed auto-migrates to compact. Normal mode scrolls collapsed thinking left during generation, then shows an opening summary; Compact mode shows only Thinking |
| Remember window state | G | On | Off ⇒ next launch uses adaptive default, centred; no writeback at exit |
| Reveal invisible characters | G | Off | Visualises zero-width / variation-selector and similar invisible characters in rendered replies. When such characters are detected you also get a notice ("N in thinking / N in output" plus the characters themselves). Detection uses a suspicious-character allowlist — zero-width and variation characters that are legitimate in CJK text are let through. Toggling clears the render cache |
| Config directory | G | — | One-click open |
| Check for updates | G | Enabled | Manual / automatic |
6.3 Settings → Recent (standalone tab)
| Field | Scope | Default | Notes |
|---|---|---|---|
| Search | — | — | Always visible; hits highlighted |
| Pinned vs Other | — | — | Independent scroll; pinned items don't disappear |
| Multi-select | — | — | Top batch bar (delete / open selected) |
| Batch open | — | Open selected | Changed from "open all" to "open selected"; beyond the concurrent-active cap, opens the first N (truncated) and says so |
| Delete | — | Inline countdown | Arm → 3s countdown → confirm; no native confirm |
6.4 Settings → Data
| Field | Scope | Default | Notes |
|---|---|---|---|
| Storage Usage view | G | — | 14 backup categories + 6 non-backup items; matches du to the byte |
| Single / batch cleanup | G | — | Sensitive-data categories write an auto-clean-<ts> snapshot first |
| Full reset | G | — | Deep-wipes 14 categories + restores defaults + writes auto-fullreset-<ts> |
| Create backup | G | — | .zbk encrypted (SM4-GCM with PBKDF2-SM3 key derivation, ShangMi; legacy AES-256-GCM backups still decryptable); 14 categories of app data |
| Restore backup | G | — | Pick .zbk → password → preview → confirm |
| Snapshot history | G | — | Lists all snapshots; deep-link supported |
| Attachments / Samples cap | G | 300 MiB | Range 1–4096 MiB; "Restore default" button |
| Data directory | G | — | One-click open (for backup / migration) |
| Sync (experimental) | G | Off | Multi-device sharing |
6.5 Settings → Context
| Field | Scope | Default | Notes |
|---|---|---|---|
| Session auto-rename | G | On | Sessions you haven't manually renamed get an LLM-suggested title after the first AI reply |
| Auto-rename exempt | — | Auto | Manually-renamed sessions permanently exempt |
| Compact threshold | G | Model-decided | Triggered when close to context limit |
| Auto-compact · trigger threshold | G | 85% | Triggers when usage reaches this share of the context window; range 50–99 |
| Auto-compact · recent messages kept | G | — | Number of trailing messages kept verbatim instead of summarised |
| Auto-compact · absolute trigger cap | G | 372000 | Combined with the percentage — whichever comes first. Only changes behaviour for models whose declared context window exceeds roughly 437K (some models declare a very large window, so a percentage alone would trigger far too late). 0 = off, percentage only. Persisted as auto_compact.max_prompt_tokens; env ZAGENT_AUTO_COMPACT_MAX_PROMPT_TOKENS |
| Auto-compact · max triggers per process | G | — | Cap on how many compactions happen within one process |
6.6 Settings → Memory palace
| Field | Scope | Default | Notes |
|---|---|---|---|
| Enable memory palace | G | On | Master switch for the memory subsystem. When off, no candidates are extracted, no memories are injected, and the message menu's "Save to memory palace" does not open the drawer (it tells you where to re-enable it). Takes effect with zero restart (the backend is deregistered / registered on the spot). Persisted as memory_palace_enabled |
| Memory entries | G | Empty | CRUD for the long-term memory store |
| Journey design | G | — | Combine multiple memories into a "journey" |
| Review panel | G | — | View by topic |
| Per-extraction cap | G | 7 | 1–10 = fixed cap; 0 or >10 = unlimited (model decides). Applies to auto / manual / re-extract |
| Draft inbox | G | — | HookStop extract → {palace}/_pending/{ts}-{slug}.md → MemoryReviewPanel to approve / edit / reject. Drafts don't enter the in-memory index or retrieval |
| Health board | G | — | Total / expired / never-recalled / per-room counts / hot Top 10 / cold ≤20 / low-value ≤20 (R≥5 and SR≤0.2) / duplicate clusters ≤20 / pending dup·conflict counts; one-click prune / merge |
| Recall weighting | G | On | RecallCount × SuccessCount; never-helpful entries sink |
| Rare-term weighting | G | On | Rarer / more distinctive terms count more — relevant entries surface easier |
| Skip-if-irrelevant injection | G | On | Memories with low relevance aren't injected; only Pinned entries are kept |
| Conflict to pending | G | On | Same S+P but different O → ConflictHint = old_id; approval supersedes the old entry. Complementary to MergeHint (triples overlap ≥ 2/3) |
| judge lesson distillation | G | On | Issues found by the self-check gate's judge checker auto-land in the draft inbox |
6.7 Settings → Models → Providers
| Field | Scope | Default | Notes |
|---|---|---|---|
| Provider list | G | AVL-Zero (shared, Delta) | Add your own providers |
| Type | G | AVL Delta-compatible (AVL-Zero) / OpenAI (others) | AVL Delta compatible / OpenAI (compatible) / Anthropic (x-api-key + anthropic-version) |
| Delta protocol switch | G | On (AVL-Zero) | Per-turn delta only; 404 / 405 / 501 falls back once per session to chat/completions; 401 / 403 doesn't downgrade |
| Add / edit | G | — | Name / endpoint / credential |
| API key management | G | Auto-issued | Fill in when self-connecting |
| Advanced → Custom headers | G | — | Your own providers only; multiple key/value rows. Applied after built-in headers, so they can override Authorization / User-Agent etc. Empty keys and entries containing CR/LF are skipped; Host header has no effect |
| Model refresh | G | — | Pull model list for the chosen type |
6.8 Settings → Models → Model settings
| Field | Scope | Default | Notes |
|---|---|---|---|
| Unselected fold | G | Folded | Each provider group only shows enabled models; "Expand N" reveals all; per-provider memory; search auto-bypasses |
| Default model | W | Provider-decided | Workspace overrides |
| Temperature | W·M | 0.7 (Landi N2.6 / N2.7: 1.0) | 0–1. The built-in AVL-Zero Landi N2.6 / N2.7 are reset once to the recommended 1.0 (once per model, recorded in the provider yaml as settings.builtin_sampling_reset_v1); later manual edits are never overwritten; "Reset to defaults" always gives 0.7 |
| Top-P | W·M | 0.95 | 0–1. 0.95 when unset; Landi N2.6 / N2.7 are likewise reset once to the recommended 0.95; "Reset to defaults" gives 0.95 |
| Context window | W·M | Follows the model config | Total context tokens the model can hold; the basis for auto-compact and the soft-threshold warning |
| Max output tokens | W·M | Follows the model config | No hard cap; values above the model's nominal limit are allowed — the upstream API enforces its real limit |
| Nominal max output | W·M | Follows the model config | The output limit declared by the model's spec; used as the default when "Max output tokens" isn't set explicitly, and checked in the window structure validation (the context window must be larger than it) |
| Call timeout | G | 30 s | Single LLM call timeout; 0 = follow the provider's API setting |
| Max steps | W·M | 0 (unlimited) | One LLM response or one batch of tool results counts as 1 step; leave at 0 for long tasks |
| Stream | G | On | Off ⇒ batched output |
| Effort | Per model | High (unset) | Built-in AVL-Zero Landi N2.7 series only; persisted as params.reasoning_effort and applies to every session using that model. Levels in §19.8 |
| Accepts image input | M | Follows the model config | When ticked, the model can receive images along with a message (paste / drag / "+" menu). Flagged out of the box for qwen-3.8-27b and the Landi N2.7 series; when not ticked the input box refuses attachments and suggests switching models |
Image input limits: at most 6 images per message; each ≤ 1536 KB after processing, 3 MB in total; PNG / JPEG / GIF / WebP only; oversized images are scaled proportionally to a 1568 px long edge; a PNG original ≤ 400 KB with acceptable dimensions is kept as-is, otherwise it is converted to JPEG (quality 0.85). Images cannot be attached while the assistant is running. Images go out only with the turn that sent them (they retire once that turn has been answered normally and the user has provided new input; volatile context records are excluded from that judgement).
Single entry point for parameter editing: all the model parameters above are edited in the Model settings drawer (the Model settings page and the Providers dialog open the same panel). Save validation: an output limit ≥ the context window is rejected; an output limit above half the window raises a warning (recommendation: context window ≥ 4 × max output); simultaneous edits in both places are checked with an optimistic lock, and conflicts are reported in place.
6.8.1 Settings → Models → Routing
| Scenario | Scope | Strategies | Default | Notes |
|---|---|---|---|---|
| Main session | G | Global / Per session |
Global | Per session: each session remembers its model, new sessions snapshot the current choice, invalid models fall back to global; automatic session naming uses the main session's model |
| Subtasks | G | Main session / Persona / Preferred model |
Main session | Preferred model adds a "When unavailable" fallback: Main session / Persona; the delegation argument model only applies under Persona |
| Routines | G | Main session / Per task / Preferred model |
Main session | Per task = the task's own model (only this strategy shows a model selector in the task dialog); unset or unavailable falls back to the main session |
| Hooks | G | Main session / Preferred model |
Main session | A model on the hook entry takes precedence |
| sec.decompile | G | Random / Lowest cost / Best quality |
Best quality | Enabled 澜砥 (Landi) models with an API key only; otherwise the session's model |
| code.ask | G | Same as above | Best quality | Same as above |
| Memory auto-extraction | G | Same as above | Best quality | Same as above |
| Auto-repair | G | Off / Ask before switching / Switch automatically |
Ask before switching | When the selected model is unavailable (provider missing / disabled / lacks the model / model disabled or retired) or the upstream fails, whether to use another provider that has the same-named model enabled, not retired and with a usable key (the first in file-name order; never a different model) |
| Keep after switching | G | On / Off | Off | Shown when the strategy isn't "Off"; when on, the provider switched to is written into the session's (Per session) or the global (Global) model selection |
- "Preferred model" candidates: enabled, online models whose provider has a usable API key (a
$VARkey must use aZAGENT_/OPENROUTER_/OPENAI_/ANTHROPIC_/ZMCP_prefix); if the chosen model becomes unusable it is marked "(unavailable)" and the fallback applies. - Cost / quality ranking: by price when every candidate has one configured; otherwise by name — tier Flash < Mid < standard, newer versions rank higher, and Preview /
-P2-style variants rank below the release of the same version. - When it takes effect: on the next call; sec.decompile / code.ask re-read the setting on every call inside the zWorkspace process, no restart needed.
- Auto-repair confirmation bar: only user-initiated send / continue generating / "Restart from here" / "Divine inspiration" in the GUI can show the "Switch to a backup model?" bar ("Switch & send" / "Not now"; on upstream failures it is "Switch & retry"); an unanswered bar is voided when a new turn starts.
- Scenarios where no confirmation bar can be shown (automatic continuation, IM, routines, subtasks, hooks, context compaction, SBOM, checks, restate intent, experience reflection, session naming, long-message summarisation, memory extraction, TUI, resuming interrupted tasks): under "Ask before switching" they don't switch and report the error directly, with a toast naming scenario / model / reason / strategy (once per scenario per model within 5 minutes); if the session already switched during this turn, these calls follow the backup. In local mode "Switch automatically" is downgraded to "Ask before switching".
- Order for deciding "which model does this turn use": local mode only accepts the model the session explicitly chose / the session's own model → under Per session, when the session recorded the default picked for the user → the current default model → the session selection under Per session, or the global selection under Global → for backend calls with no selection, the model this session last used in this process → the current default model (AVL-Zero / "澜砥 N2.6"). A model the user picked is returned as-is even if unavailable and handed to Auto-repair. Turns the app starts by itself (compaction continuation / goal continuation / todo check-in / self-heal / test gate / task resume / "Continue") all use this decision.
- Local mode override: when the session is in local mode the strategies above are ignored — code.ask / sec.decompile / memory extraction use only the session's model; subtasks use the main session's model; hooks use the triggering session's model (if it can't be determined, that hook's model call is skipped); routines posted into that session use its model.
[!warning] Code snippets retrieved by code.ask, sample bytes sent by sec.decompile, and session content used for memory extraction go to the 澜砥 model chosen by routing (usually the built-in AVL-Zero cloud), not necessarily the current session's model; the
provider/modelfields in the result show where they went.
6.9 Settings → Plugins
| Field | Scope | Default | Notes |
|---|---|---|---|
| View toggle | G | Installed view | Installed ↔ Market, two-layer breadcrumb |
| Installed list | G | Empty | Enable / disable / uninstall (inline confirm) |
| Browse marketplace | G | Default market | Add / switch market sources; filter by category or disclosed capability |
| CC plugin adapter | G | On | Compatible with Claude Code plugins: github@<org>, owner/repo, git remotes |
| Pre-install confirm | G | On | Lays out source / commands / capabilities / signature before installing |
| Active by default in workspace | W | On | Global plugins enabled per-workspace; marketplace install activates immediately |
| Permission settings | G | Ask | Plugin's allowed tool scope |
| Auto-update | G | Ask | Check at launch |
| Refresh marketplace from source | G | — | Re-fetch an added marketplace source (git re-pull / local re-parse); the view surfaces installed version + "Upgradable" marker, upgradable from the row or card |
| Check for updates (installed) | G | — | Header "Check for updates" finds upgradable installed plugins; an updatable card shows an "Update available" badge + Upgrade button |
| Upgrade mechanism | G | — | semver-first version comparison + diff fallback; plugin directory cleared before upgrade (no stale components); marketplace cache uses an atomic swap with rollback |
| Inline progress | G | — | Install / upgrade / preview / update / add show an inline progress bar (real git-clone progress); update / check buttons are an in-place spinning refresh icon |
| Source-trust shield | G | — | Plugin cards show source-trust status next to the author (same marker as the zMarket store); model-provider entries reuse the owning plugin's icon, and the "Plugin" badge is a neutral outline |
| Import identity | G | — | A zip-imported plugin's name is taken from the signed manifest, not the filename; a zip sharing a name with an existing plugin no longer silently reuses the old directory |
Typical plugin catalogue: the official plugin marketplace provides 22 typical plugins (source maintained in the repository) — 15 model providers (DeepSeek / OpenRouter / OpenCode Zen / OpenCode Go / MiniMax / Xiaomi MiMo pay-as-you-go + Token Plan / Zhipu / Moonshot Kimi / Qwen / Doubao / Ollama / SiliconFlow / StepFun / an OpenAI-compatible template) + a Zhihu toolkit + 4 native-capability demos (tools / hooks / channels / skills) + 2 CC compatible-format demos (agents+commands, mcp+hooks). In-conversation plugin management: the four tools
PluginSearch/PluginList/PluginInstall/PluginUninstallrun the plugin lifecycle inside a session; write operations use the dry_run → confirm two-step (see the note in §11.1).
6.10 Settings → Hooks
| Field | Scope | Default | Notes |
|---|---|---|---|
| Pre-tool-call confirm | W·M | Per-tool defaults | Three-state: allow / ask / deny |
| Auto-approve list | W | Empty | "Always allow" writes here |
| Tool deny-list | W·M | Empty | Hard-disable specific tools |
| Error drawer | W | — | Auto-keeps last 100 entries |
| Hook execution visibility | — | On | Each hook run is a collapsible system message in the conversation stream (Markdown) |
| Plugin hook root | — | Auto | CLAUDE_PLUGIN_ROOT points at the plugin dir; SessionStart and other hooks fire reliably |
6.11 Settings → Agents
| Field | Scope | Default | Notes |
|---|---|---|---|
| Agent list | G | 5 built-in + user-defined | Source tag: built-in / global / workspace |
| Name | G | Built-in | Display |
| Personality | G | Built-in | Short style |
| System prompt | G | Built-in | Can point to a workspace file |
| Mode binding | W | Default mapping | One persona per mode |
| Edit / duplicate / delete | G | — | Only global / workspace sources are editable |
6.11.1 Settings → Reflection (new tab in the Agent group)
Consolidates the three "autonomy & self-reflection" toggles in one place (tab id reflection, Brain icon, Agent group).
| Field | Scope | Default | Notes |
|---|---|---|---|
| Restate intent (confirm before starting) | G | On | Persisted key intent_confirm (schema v8, default true). Triggers only on the first hand-typed message, and only when it's short (≤30 chars shortFirstMsgRunes) or simple (not multi-line / list, ≤3 separators, ≤80 chars simpleMaxRunes); multi-agent mode gives a phased plan. Three choices: Confirm & start / Edit (goal+plan) / Keep my original (intent.confirm.keepOriginal, continue with the original message). The "Analyze intent & restart from here" message-menu item forces it (hiding messages after the restart point). See the User Manual, "Sessions", §5.4.1 |
| Intent restatement choice stats | G | — | A separate YAML records counts + char totals for Confirm / Edit / Keep original / Auto-start (timeout) / Cancel; shown on this page as a table (Category / Count / Chars) |
| Auto-reflect (retrospective learning) | G | Off | Persisted key auto_reflect. On multi-step task wrap-up, runs a GRAI+KISS retrospective (over the trace + self-heal stats) and sediments Keep/Improve/Stop/Start lessons to memory for review; costs an LLM call (see §18.6) |
| Auto-resume interrupted tasks | G | Off | Persisted key auto_resume_tasks. When on, a restart auto-continues background tasks left unfinished by a crash / kill; startup auto-resumes at most 5, the rest stay in the "Interrupted" status strip for manual resume (see §18.4) |
These three previously lived in the General tab; they moved to the Reflection tab in this release.
6.12 Settings → Skills
| Field | Scope | Default | Notes |
|---|---|---|---|
| Skill list | G + W | Empty built-in | Three sources (global / workspace / plugin); built-in skills (e.g. skill-creator) carry a "Built-in" badge |
| Loading strategy | W | Auto | Refresh at launch |
| Install / delete | G | — | Drop a folder or scan a directory |
Signature verification, the signing verification policy and the trust store have moved to the standalone Settings → Skill/Plugin Signatures tab (Security group, see §6.17.1).
6.13 Settings → Routines
This page only manages workspace routines (each run creates a new session). Session routines that the AI sets inside a session with
RoutineCreateare not shown here — see §18.7.
| Field | Scope | Default | Notes |
|---|---|---|---|
| List | G | Empty | Grouped by source workspace |
| Toggle on / off | G | On | Same ui/Switch as elsewhere |
| Run now | G | — | Trigger one run immediately |
| Recent run traces | G | — | Inline expand; per-run sessions |
| Cross-workspace grouping | G | — | Unopened workspaces show a badge + "Open" button |
| Search | G | — | By routine name or workspace name |
Schedule parameters:
| Field | Type | Default | Notes |
|---|---|---|---|
type |
enum | manual | hourly / daily / weekdays / weekly / manual |
weekdays |
array | — | [1..7]; "Weekdays" / "Weekend" presets |
time (HH:MM) |
string | — | Hour / minute two-column dropdowns. hourly reads only the minute, hour locked to 00, trigger label :MM; NextRun is the closest matching-minute mark after after, +1 h if collided / passed; day boundaries / DST handled correctly via time arithmetic |
command |
string | — | The instruction sent to the AI on trigger |
mode |
string | auto | Same five modes as a normal session |
model |
string | — | Same model picker (search by group) |
Run behaviour:
- Each run creates a regular session in the workspace; reviewable.
- A routine that's still running skips the next trigger — no stacking.
- Manual schedule (no time): immediately triggers one round on save; button reads "Run once" thereafter.
6.14 Settings → Messaging
| Field | Scope | Default | Notes |
|---|---|---|---|
| Channel | G | WeChat / Feishu / DingTalk supported | |
| QR sign-in | G | — | Per-channel QR |
| Binding code | W | 6 digits | 10-minute TTL |
| Workspace routing | W | Default session | See §4.2 |
| Throttling | G | min 200 / idle 3s / max 3800 | Char counts |
| Unbind | W | — | Immediate |
6.15 Settings → Data masking
Config file: ~/.config/avlcode/redaction.yaml; main process and child processes share the pkg/redact engine.
| Field | Scope | Default | Notes |
|---|---|---|---|
Master switch enabled |
G | Off | Opt-in; when off, every scope passes through |
scopes.export_html |
G | On (after master) | Applied on HTML session export; rules apply to the decoded JSON text values and recurse into nested JSON (covering tool-call args and results), fixing line-start IPs in code blocks and deep fields that were missed |
scopes.export_session |
G | On (after master) | Applied on .zsession export (same; covers line-start IPs in code blocks) |
scopes.write_md |
G | Off | On-disk redaction when AI writes .md etc. (Phase 2) |
presets.secrets |
G | Off | Built-in secret-rule pack (below) |
rules[] |
G | Empty | User rules; rules ∪ presets is the final compile input |
Rule fields:
| Field | Type | Notes |
|---|---|---|
type |
enum | keyword / regex / ipv4_mask / domain_mask |
pattern |
string | keyword auto-escaped; regex RE2 |
replacement |
string | Literal for keyword; regex supports $1 / ${name} templates |
octets |
int[] | ipv4_mask segments to redact (1-based, 1..4, any incl. middle) |
segments |
int | ipv4_mask legacy: mask first N segments |
keepLast |
int | domain_mask trailing labels to keep (default 1) |
maskChar |
string | ipv4 / domain mask character (default *) |
enabled |
bool | Per-rule toggle |
label |
string | Audit label on hit |
Built-in secrets preset: AWS Access Key (AKIA…) · GitHub PAT (ghp_…) · GitHub Token (gh[osu]_…) · Slack Token (xox[baprs]-…) · Stripe Live Key (sk_live_…) · GCP API Key (AIza…) · OpenAI Key (sk-…) · PEM private-key block (head + body + tail, multi-line).
Hit feedback: each redaction completion pops a toast — hit count + matched rule labels.
6.16 Settings → Supply chain / SBOM
Configures the vulnerability-DB sources and local offline DB for sbom.audit / sbom.vex:
- Config file
<config>/sbom.json; blank fields = built-in defaults (direct public access); bad / missing JSON fails safe to defaults and never blocks an audit. - The save button is "Test & Save": it first validates format (URLs must be http/https, proxy http/https/socks5, paths free of null bytes), then probes availability per
default_mode(local-DB-path writability is always blocking; offline mode skips network probes); if any blocking item is unavailable it refuses to save and lists the reasons. - Offline fields (local vulnerability-DB path, etc.) are grouped under the "Offline vulnerability DB" section; relative paths are normalized to absolute paths on test and written back.
- "Reset to defaults" only changes the form, nothing is persisted; click "Test & Save" to apply.
- Backend bindings:
SBOMGetSettings/SBOMSetSettings/SBOMSyncDB/SBOMOpenVulnDBDir/SBOMTestSettings.
Data sources:
| Field | Persisted key | Default | Notes |
|---|---|---|---|
| OSV online query API | osv_api_base_url |
https://api.osv.dev |
Query endpoint for online audit |
| OSV offline dump source | osv_bucket_url |
https://osv-vulnerabilities.storage.googleapis.com |
Bucket dbsync sync pulls per-ecosystem dumps from |
| KEV catalog source | kev_url |
CISA KEV feed | Known-Exploited-Vulnerabilities catalog URL |
| Local vulnerability DB path | vulndb_path |
<config>/vulndb |
Offline DB directory; may point at a read-only mount; "Open folder" provided |
| HTTP proxy | http_proxy |
empty | Blank falls back to HTTPS_PROXY / NO_PROXY env vars |
| Default audit source | default_mode |
auto |
auto (offline if a local DB exists, else online) / online / offline |
Offline DB: a per-ecosystem table (Ecosystem / Records / Freshness — unknown / today / Nd ago / Source) plus the KEV entry count; a multi-select ecosystem dropdown (with filter, select-all / clear) drives Sync (per-ecosystem progress bar) and a Sync KEV button. Syncable ecosystems come from the backend SyncableEcosystems (the 13 with OSV offline-dump coverage).
Air-gap note: point the sources above at an internal mirror (add a proxy if needed), fill the local DB via
sbom.dbsync syncor offlineimport, andaudit/vexthen run fully offline.
6.17 Settings → Security (threat detection · Sentinel · VT/GTI)
The config page for VirusTotal / GTI cloud threat intelligence (tab id security). Persisted in <config>/vtai.yaml; keys are encrypted on-device. Detection capability is decoupled from Sentinel interception — configuring a backend / YARA lets the Agent call the scan tools without turning interception on. Four sections:
① Threat detection
| Field | Persisted key | Default | Notes |
|---|---|---|---|
| Cloud detection service (single-select) | mode |
empty (none) | vtai = VirusTotal AI · free-hosted (hashes / suspicious files uploaded for public analysis, alias on leaderboard); user_key = Google Threat Intelligence · your own key (results not public, needs the key below, greyed when no usable key); "" = no cloud. Legacy local migrates to "" + yara_enabled |
| Upload files to cloud scan | auto_scan |
off | on = allow full-scan uploads (sensitive files like keys / .env are never uploaded); off = hash-only |
| Local YARA rules | yara_enabled |
off | independent toggle, fully offline; can run with the cloud; changing the rules directory reloads on workspace restart (not hot-reload) |
| Reset to defaults | — | — | Non-destructive: mode="" + auto_scan=false, keeps key / registration / api_base / full_tools |
| Re-fetch key (VirusTotal AI) | — | — | RefreshVTAIKey: re-registers with the existing identity for a new token (machine change / rotation) |
② Auto-scan interception · Sentinel: a single switch (merging enabled+monitor); when on, the Agent's file read / write / execute is auto-scanned and malicious hits blocked; greyed until a detection method is configured (capable = mode≠"" or yara_enabled).
③ Google Threat Intelligence key: API Key (encrypted on-device; shared by the user_key cloud and vt.*; entering it alone enables nothing) + Custom service URL (default https://www.virustotal.com/api/v3, for enterprise / internal mirrors). The VirusTotal AI free-hosted backend also supports its own custom endpoint (independent of the GTI URL). Display names are the full VirusTotal AI / Google Threat Intelligence.
④ vt. full intelligence tools*: master switch (greyed without a usable key) + sub-toggles Query-only mode (default on) / Enable paid features (default off) / Confirm before uploading a sample (default on, shown only when query-only is off); once enabled, shows an effective-state summary ("Currently: query-only|read-write · paid endpoints|free only · custom endpoint").
The panel copy is hardcoded (no i18n). Backend Wails:
GetVTAIState/SetVTAIMode/SetVTAIYaraEnabled/RefreshVTAIKey/GetVTAILeaderboard,GetVTFullToolsState/SetVTFullToolsPolicy/SetVTFullToolsAPIKey/SetVTFullToolsAPIBase;HasAPIKeyusesKeyUsable.
6.17.1 Settings → Skill/Plugin Signatures (standalone tab)
The signing verification policy and the trust store, previously split across the "Security" and "Skills" pages, are consolidated on this standalone tab (Security group, tab id signatures); one policy governs both skills and plugins:
① Signing verification policy (three tiers; switching auto-heals legacy inconsistent state):
| Tier | Semantics |
|---|---|
strict |
Unsigned or failed-verification skills / plugins are neither loaded nor installed |
warn |
Failed verification can still pass but is flagged in the UI; a package with unverifiable provenance now pops a confirmation and lets the user decide whether to let it through, while a package with evidence of tampering is still hard-blocked |
skip |
No cryptographic verification; only manifest metadata is read |
② Trust store:
| Field | Notes |
|---|---|
| Trust-store path | Default or custom path; signer_roots/ holds signing root-CA PEMs, tsa_roots/ holds TSA root CAs (for full timestamp verification) |
| Reload | Manual reload button + auto-reload; dropped-in certificates take effect immediately, no restart |
| Import root certificate (PEM) | File-picker import; written into the trust store and counted towards the signer / TSA anchor totals immediately |
| Anchor counts | The panel shows "🔑 Signer anchors N · 🕒 TSA anchors N", with one-click open of the trust-store directory |
Rejections / import failures surface the specific reason (signature chain, timestamp, tamper point) — not a generic error.
