decisions

Use Settings Driven Taxonomy And Navigation Model

Context

Earlier Forma design treated Space as the core partition concept. That was a useful simplification while removing the older collection terminology, but the WebApp design review exposed a deeper issue: Pages, Spaces, Views, Dashboard content, and graph projections should come from one explicit configuration model rather than from several special built-in concepts.

Choral Forma should stay repository-native. A workspace should be understandable from ordinary files plus one clear configuration entry, without hidden product logic such as "Spaces always exist" or "Pages is always the global uncategorized index".

Decision

Use a settings-driven model centered on a repository-level .forma.md configuration entry.

.forma/ remains only a recommended conventional directory for supporting configuration, templates, view definitions, or assets. It is not a privileged location by itself. Paths in .forma.md are resolved from the directory that contains .forma.md, unless a field explicitly says otherwise.

The minimal built-in model is:

  • Page: a renderable Markdown-backed knowledge entry.
  • Taxonomy: a configured classification system over pages.
  • Term: one value inside a taxonomy.
  • View: a configured projection over pages, terms, references, or other derived read-model data.
  • Dashboard: a configured workspace home node whose body can provide introductory Markdown and a generated-content slot.

Taxonomies are user-configurable. A taxonomy can use:

  • mode: primary when a page should have one main term for that taxonomy.
  • mode: multiple when a page can belong to multiple terms.

Term membership is scoped by taxonomy. A page may belong to terms from multiple taxonomies at the same time. Within one mode: primary taxonomy, a page should resolve to at most one term. Within one mode: multiple taxonomy, a page may resolve to more than one term.

The familiar "Spaces" experience should be produced by a configured primary taxonomy, not by a unique hardcoded product concept. Starter workspaces may configure a taxonomy named spaces, but the core should not require that exact taxonomy.

Navigation is a WebApp responsibility rather than a service-side configuration contract. The default WebApp sidebar can be derived from built-in routes plus configured taxonomies and views. This keeps the backend focused on read-model configuration while leaving product navigation layout to the GUI. If custom navigation becomes necessary later, it should be introduced as a separate WebApp-facing feature instead of being assumed by the first public config contract.

Display concerns should use an explicit display object. The first supported field is display.order; future display.icon, display.color, and display.title can be added without changing the underlying model.

Templates and create behavior attach to taxonomy terms or other explicit configuration nodes. They should not be implicitly tied to a unique Space concept.

Consequences

  • The target configuration entry is .forma.md.
  • .forma/ can still be used in examples and docs as a conventional support directory.
  • Space and taxonomy definitions are loaded through explicit .forma.md import patterns rather than a dedicated registry file.
  • WebApp navigation should be generated by the WebApp from system routes and read-model data rather than from a committed navigation.yml service configuration.
  • Pages with no primary taxonomy term do not need a special built-in Inbox or Uncategorized term. They can be surfaced by a configured view or navigation group.
  • Current P0 checks enforce unique membership for the spaces projection used by the current read model. General mode: primary taxonomy membership validation should be added when taxonomy discovery is generalized beyond the current spaces compatibility surface.
  • Raw workspace serving should not expose hidden internal config by default. Public assets should live in ordinary public workspace paths such as assets/logo.svg, not under privileged internal config paths.
  • The first public release can make breaking changes because no stable public config contract has shipped yet.

Alternatives Considered

Keep Space As The Core Built-In Partition

This is simpler but makes one taxonomy special forever. It also creates awkward rules for unassigned pages, multi-space pages, and future taxonomy-like concepts such as tags, categories, teams, or project areas.

Make Spaces A Preset View Only

This removes one special concept, but a taxonomy is a better fit because Spaces classify pages and can drive schema, creation, display, and navigation behavior.

Use Hugo-Style Built-In Tags And Categories

Hugo is a useful reference for taxonomy behavior, but Choral Forma should not ship built-in taxonomy names. Starter workspaces can provide common examples, while the core stays generic.

Put All Support Files Under .forma/

This keeps configuration tidy, but it makes .forma/ a semi-hidden product store. The preferred model is one explicit .forma.md entry with ordinary paths for assets and optional supporting files.