Skip to main content

Templates

Field Types and Options

Templates define the fields available on artifacts of a given type. Each field has a type, which determines what kind of value it can hold and how it renders.

The types

TypeDescriptionUI
textFree text, optionally constrained to predefined optionsInput or dropdown
numberNumeric valueNumber input
dateISO date stringDate picker
booleanTrue / falseToggle
relationshipLink to one or more artifacts of a specific template. See Relationship fields below.Chips + picker
userReference to a team member in the projectAvatar + picker

Field options for text

A text field can be either free-form or constrained:

  • Free text: any string.
  • Constrained: users pick from a predefined list of options. Each option has a label, value, description, and display color/icon. Used for status, priority, size, and anything else enum-shaped.

multiple: true vs. single

For relationship and constrained-text fields, set multiple: true to allow selecting more than one value. Default is single-select.

required: true

Mark a field required and Spruce blocks artifact creation until it's set. Useful for fields that are meaningless at default (e.g., severity on an incident).

defaultValue

Set a default value, particularly useful on status so new artifacts land in the right workflow state automatically (e.g., status.defaultValue: Todo for tasks).

Display hints

  • pinned: show the field as a chip in the artifact header and on view cards.

See Creating a Template → Display properties for per-option display (color, icon) and the broader display-properties story.

Relationship fields

A relationship field links artifacts to other artifacts. Use it to define parent / child structures, sibling references, or any cross-type linkage your workflow needs.

Anatomy of a relationship field

yaml

tasks:
  type: relationship
  template: task
  label: Tasks
  multiple: true
  required: false
  description: Related tasks that implement this feature

Key parts:

  • type: relationship: marks this as a relationship field.
  • template: task: the target template name. Can be any template (built-in or custom).
  • multiple: true: allow linking many artifacts. Set to false for a single reference.
  • label: shown in the editor and on cards.
  • description: helper text.

One-to-many vs. one-to-one

  • One-to-many: multiple: true, e.g. a feature's tasks (a feature has many tasks).
  • One-to-one: multiple: false, e.g. a bug's originating_feature (each bug has at most one parent feature).

Spruce enforces the multiplicity at edit time.

Cross-template relationships

A relationship can target any template, built-in or custom. Example: an incident template with a related_features relationship targeting feature:

yaml

related_features:
  type: relationship
  template: feature
  label: Related Features
  multiple: true

Rendering

Relationship fields render inside the artifact body. Each linked artifact shows as a chip, clickable to navigate, removable from the relationship.

In any view, you can add a relationship field to Visible fields to show it on artifact cards (e.g., a feature card showing its task count).

Circular and self-referential

Spruce allows circular relationships: two artifacts can reference each other via different fields. It does not auto-sync inverse references; if you add feature B to feature A's related_features, feature B doesn't automatically get feature A added back. Manage both sides yourself.

A field can reference its own template (template: feature on a feature template), useful for "depends on" / "blocks" relationships.

Example field definitions

yaml

schema:
  status:
    type: text
    label: Status
    required: true
    defaultValue: Todo
    hints: [pinned]
    options:
      - { value: Todo, label: Todo, display: { color: '#f97316', icon: circle-dot } }
      - { value: 'In Progress', label: 'In Progress', display: { color: '#3b82f6', icon: progress } }
      - { value: Done, label: Done, display: { color: '#22c55e', icon: circle-check } }

  severity:
    type: text
    label: Severity
    required: true
    options:
      - { value: 'SEV-0', label: 'SEV-0', description: Total outage }
      - { value: 'SEV-1', label: 'SEV-1', description: Major degradation }
      - { value: 'SEV-2', label: 'SEV-2', description: Partial outage }
      - { value: 'SEV-3', label: 'SEV-3', description: Minor issue }

  assignee:
    type: user
    label: Assignee
    required: false
    hints: [pinned]

  related_features:
    type: relationship
    template: feature
    label: Related Features
    multiple: true
    required: false