# ~/.config/ontoref/schemas/ontoref-project.ncl — ProjectEntry contract. # Installed by `just install-daemon`. Imported by per-project .ontoref/project.ncl files. let KeyRole = [| 'admin, 'viewer |] in let KeyEntry = { role | KeyRole, hash | String, label | String | default = "", } in # Maps ONTOREF_ACTOR value → role name declared in scopes/.ncl. # Example: { developer = "developer", ci = "cdci", ontoref = "ontoref" } let actor_key_bindings_type = { _ | String } in let VaultBackend = [| 'restic, 'kopia |] in # Per-file recipient routing (optional). When `recipient_rules` is declared, # bootstrap generates /.sops.yaml from these definitions and sops # encrypts each file with the union of recipient groups matching its path. # Use case: multi-tenant projects where different clients/agents/teams # decrypt different credential files within the same vault. let recipient_group_type = { _ | Array String } in # group → list of age1... pubkeys let recipient_rule_type = { path | String, # path_regex relative to vault dir groups | Array String, # union of these recipient_groups } in let SopsConfig = { enabled | Bool | default = false, # Slug used for ~/.config/ontoref/vaults//. Defaults to project slug when absent. vault_id | String | optional, # Restic or kopia. Switching requires re-initializing the local repo. vault_backend | VaultBackend | default = 'restic, # ZOT registry endpoint where src-vault/:latest is pushed/pulled. registry_endpoint | String | optional, # Paths to age public key files for each declared recipient (relative or absolute). age_key_paths | Array String | default = [], # Path to the master age private key (.kage). Overrides the global path in config.ncl. # Never store this inside the vault directory or the project root. master_key_path | String | optional, # ONTOREF_ACTOR → role name binding. Used by credential resolution to select the correct # sops-encrypted file in scopes/.ncl before calling oras. actor_key_bindings | actor_key_bindings_type | default = {}, # Per-file recipient routing — empty = use SOPS_AGE_RECIPIENTS env (legacy mode). recipient_groups | recipient_group_type | default = {}, recipient_rules | Array recipient_rule_type | default = [], } in let ProjectEntry = { slug | String, # Absolute local path to the project root. Empty string for push_only projects. root | String, # Import paths for nickel export on this project's NCL files (local projects only). nickel_import_paths | Array String | default = [], # Auth keys for this project. Empty = no auth required. keys | Array KeyEntry | default = [], # Remote URL for push_only projects (git, SSH, HTTPS). Informational — not accessed by daemon. remote_url | String | default = "", # When true: no local file watch, no NCL import. Project pushes ontology via POST /sync. push_only | Bool | default = false, # Registry credential vault configuration. Absent = no registry credentials declared. sops | SopsConfig | optional, } in { make_project = fun fields => fields | ProjectEntry, make_remote_project = fun fields => (fields & { push_only = true, root = "", nickel_import_paths = [] }) | ProjectEntry, }