Skip to content

Third field category “internal” #7

@MHohenberg

Description

@MHohenberg

firm add currently treats fields as required or optional. Some fields (e.g., created, updated) are system-managed and shouldn’t be user-editable during interactive entry. Introduce a third category - internal - to mark fields that are set by Firm (or derived) and hidden or read-only in interactive flows.

Motivation

  • Reduce friction: users shouldn’t have to tab through non-editable metadata just to reach the single optional field they actually want.
  • Prevent accidental edits: timestamps and integrity fields shouldn’t be user-supplied.
  • Clearer intent: schemas can express “who owns this value” (user vs. system) rather than just “is it required.”

Proposal

1) Add per-field properties:

field "created" {
  type       = "datetime"
  mode       = "internal"    # "required" | "optional" | "internal"
  compute    = "now()"       # optional: function or template
  editable   = false         # default for internal
  visible    = "hidden"      # "visible" | "hidden"
}

field "updated" {
  type       = "datetime"
  mode       = "internal"
  compute    = "now()"       # auto-set on create; update hook bumps this
  on_update  = "now()"       # recompute on mutation
}

field "name" {
  type       = "string"
  mode       = "required"    # prompted
}

field "notes" {
  type       = "string"
  mode       = "optional"    # prompted after requireds
}

Some notes:

  • mode=internal implies editable=false in interactive prompts and CLI flags.
  • compute/on_update let Firm populate values automatically.
  • visible=hidden keeps internal fields out of firm add prompts and short views, while still persisting in the file.

2) CLI Behaviour (firm add)

Prompt order: required → optional. Internal fields are skipped.

Flags:

  • --show-internal (view-only) prints computed/internal fields at the end.
  • --no-optional jumps straight to save after requireds.

Validation:

  • If a user provides an internal field via --field created=..., reject with a clear error: “Field ‘created’ is internal and cannot be set interactively.”

Hooks:

  • On create, evaluate compute.
  • On update/mutate, evaluate on_update for relevant fields.

Backward compatibility

  • existing schemas default to mode="optiona" when no mode is specified, preserving behaviour

Risks / Considerations

  • Need a deterministic set of compute functions (e.g. now(), uuid(), hash(fields...)) to avoid non-reproducible builds

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request
    No fields configured for Feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions