Skip to content
NeuroDock

Profiles

The profile is the single cross-cutting consent and preference manifest for NeuroDock. Every MCP server reads it. Every skill respects it. The CLI installer writes it. It lives at ~/.neurodock/profile.yaml by default.

After this page you will know why the profile is local-first, what the five blocks declare, and how forward-compatibility lets you upgrade and downgrade without losing data.

NeuroDock checks four places, in order. The first one it finds wins. Most people only ever need the second one (the home-folder default).

flowchart TD
  start([Server starts]) --> e1{NEURODOCK_PROFILE_PATH<br/>env var set?}
  e1 -->|yes| use1[Use that path<br/><i>test/CI override</i>]
  e1 -->|no| e2{$XDG_CONFIG_HOME/<br/>neurodock/profile.yaml?}
  e2 -->|yes| use2[Use it<br/><i>Linux convention</i>]
  e2 -->|no| e3{~/.neurodock/<br/>profile.yaml?}
  e3 -->|yes| use3[Use it<br/><i>the default</i>]
  e3 -->|no| e4{./profile.yaml<br/>in current dir?}
  e4 -->|yes| use4[Use it<br/><i>project-local</i>]
  e4 -->|no| def[Fall back to safe defaults]

Three independent consent gates govern whether anything leaves your machine:

  • privacy.embeddingslocal | cloud_voyage | cloud_openai. Default: local.
  • privacy.telemetryoff | local_otel_only | full. Default: off.
  • privacy.os_idle_consent — boolean. Default: false.

Each is independently opt-in. The default install does not phone home and does not read your OS idle state. Choosing cloud_* for embeddings triggers a visible session-start notice every time you launch a client. This is a manifesto property, not a configuration accident.

Every default in the profile is chosen because it is the safer ND-friendly value, not because it is industry-neutral:

  • motion: "reduced" — no animation by default.
  • output_format: "answer_first" — the answer comes first; rationale follows.
  • reading_font_hint: "atkinson_hyperlegible" — evidence-based readability.
  • max_chunk_size: 7 (with 5 as the ADHD-tuned preset override) — Miller’s number neighbourhood.
  • sycophancy_check: "warn" — guard fires but does not refuse.

A user who never touches their profile gets the safer behaviour. Less-safe behaviour is opt-in.

The schema is additionalProperties: true at every nesting level. This means:

  • A v0.1 loader reads a v0.2 profile without crashing.
  • Unknown keys are preserved on round-trip — they are not silently stripped.
  • Known keys are validated strictly — out-of-range integers and bad enum values are still hard errors.

The forward-compat rule is the central correctness property of the schema. See ADR 0004 for the rationale and the rejection of strict-schema alternatives.

A profile MAY declare extends: to inherit from a preset bundled with the profiles/ package:

extends: "profiles/adhd"
identity:
display_name: "T"
neurotypes: ["adhd"]

The preset’s fields are merged shallowly with the local file winning on every key. v0.1 supports single-level extension only; deep chaining (preset extending preset) is deferred to a future RFC.

The nine bundled presets — adhd, audhd, ocd, dyslexic, dyspraxia, low-stimulation, burnout-recovery, educator-semester, student-university — ship sensible bundles without forcing users to hand-author every field. See the profiles reference for a one-line summary of each.

The schema cannot accidentally collect email, real name, or date of birth — those fields don’t exist. display_name is free-form (one letter is fine). neurotypes is self-ID. That is by design.