Skip to content

FactorySettings

The Software Factory settings document: the tenant-wide factory settings the console's Settings page edits. Fields, YAML, HCL and CLI samples, and how apply treats it.

Checked against config-schemas@v1.15.0, terraform-provider-resolve@82cb23c, cli@v4.9.1

The Software Factory settings document: the tenant-wide factory settings the console’s Settings page edits. One per tenant. Each field is one setting, and its dotted path (autonomy.max) is the key the console, the API and the audit trail name it by. A field left out means the setting’s default, so applying a document resets every setting it does not name, and an export lists only the settings that differ from their defaults. Applying saves a new revision of the document through the console’s own writer, with one audit entry per changed setting; status.revision is the revision saved. The security scanner settings are the ScannerProfile document, the managed organisations are FactoryManagedOrg documents and the web push defaults (notify.push.defaults) are the NotificationDefaults document, so none of them appears here. Read-only settings (forge.polling.forbidden, firewall_enabled, systemone.min_confidence.adapter) are not part of the document.

apiVersion vulnetix.com/v1
kind FactorySettings
Group Factory
Status Served. The config engine plans and applies it.
Objects per tenant one (metadata.name: default)
Token and role An owner or admin session, or a vmt_ config management token with the owner or admin role that lists FactorySettings in its kinds. See Management tokens.
Terraform resource vulnetix_factory_settings, imported by name (see Terraform and OpenTofu)
CLI vulnetix config apply, CLI v3.168.0 and later.
Pinned schema v1.15.0/FactorySettings.schema.json
Newest schema latest/FactorySettings.schema.json
First released in v1.6.0
Print the built-in copy vulnetix config schema FactorySettings

Minimal

Only the fields the kind requires. From examples/FactorySettings/minimal.yaml.

YAML

# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/FactorySettings.schema.json
apiVersion: vulnetix.com/v1
kind: FactorySettings
metadata:
  name: default
spec: {}

HCL (resource vulnetix_factory_settings)

# Only the arguments the kind requires. From config-schemas examples/FactorySettings/minimal.yaml.

resource "vulnetix_factory_settings" "default" {
}

CLI (applies it)

export VULNETIX_CONFIG_TOKEN=vmt_...   # a config management token
vulnetix config apply -f - --manager gitops:acme/platform --auto-approve <<'EOF'
# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/FactorySettings.schema.json
apiVersion: vulnetix.com/v1
kind: FactorySettings
metadata:
  name: default
spec: {}
EOF

Advanced

Every field the kind supports, with a when expression where it takes one. From examples/FactorySettings/advanced.yaml.

YAML

# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/FactorySettings.schema.json
apiVersion: vulnetix.com/v1
kind: FactorySettings
metadata:
  name: default
  labels:
    team: platform
  annotations:
    vulnetix.com/owner: platform@acme.example
spec:
  scope:
    interest: scanned_or_pix
    archived: true
    dependencies: false
    sync: 1h
  autonomy:
    max: auto_merge_low_risk
    default: suggest
    concurrency: 8
    claim_ttl_minutes: 60
    max_attempts: 3
    no_host_ttl_hours: 6
    parked_concurrency: 50
    plan_approval: true
  belai:
    mode: goal
    ask_permission: false
    guardrails: "on"
    tests:
      post_end: goal
      on_fail: fix
    show_internal_work: decisions
    auto_commit_per_task: true
    a2a:
      show: true
  factory:
    fanoutCap: 6
  systemone:
    model: clef-flash
    min_confidence: 0.85
    below_threshold: escalate_human
    on_abstain: escalate_human
    fallback: jev
    retention: full_400d
    override: true
  pix:
    classifier: clef
    jevDailyCap: 2000
    extensionMode: packs_only
    size: medium
    egressMode: deny_except_allow
    versionPolicy: safest
    maintenance:
      - days:
          - sun
        start: "02:00"
        end: "04:00"
        tz: Australia/Melbourne
    reservePercent: 20
  crews:
    lease: 30m
  agents:
    max_cost_usd_per_item: 12.5
    finalize_at: 0.8
    max_attempts: 0
    max_continuations: 0
    max_passes_per_item: 0
    max_wall_minutes: 0
    max_iterations: 0
  forge:
    branch_prefix: factory/
    pr_state: ready
    protected: true
    check_runs: false
    read:
      default: posture_mirror
    stale:
      repo: 12h
      pulls: 10m
      checks: 2m
      alerts: 1h
    poll:
      fallback: conditional_poll_10m
    etag: true
    quota:
      factory_share: 15
      reserve: 20
      on_exhausted: pause_live_reads
      proactive_writes_per_hour: 60
    calls_per_hour: 5000
  kanban:
    mode: all
    opt_out_label: no-factory
    conflict_comment: true
  signing:
    mode: required
    auto_add: true
    email: primary
    rotate_days: "180"
    retire_days: "30"
    on_missing: readd
  hosts:
    runOn: label:linux-large
    runOnFallback: none
  approve:
    sensitive_paths:
      - .github/workflows/**
      - infra/**
  tea:
    publish: on_release_tag
  jail:
    enforcementMode: enforce
  budget:
    factory_share: 75
    month: 50000000
    on_exceed: switch_to_pix_allocation
    alerts:
      - 50
      - 75
      - 90
      - 100
  providers:
    code: pix-smart
  vault:
    grant:
      mode: specific
      entries:
        - ve_ci_token
    on_error: pause_affected_workflows
  persistence:
    retention: 400d
    postgres: "on"
    export: manual
  schedules:
    tz: Australia/Melbourne
    blackout:
      - from:
          day: fri
          time: "17:00"
        to:
          day: mon
          time: "08:00"
        label: weekend
    missed: run_once
  audit:
    calls: true
    sign: true
    weekly_report: true
  notify:
    events: escalations_holds_budget
    connector: teams
  defaults:
    enabled: true
    pr-review:
      enabled: true
    ci-fix:
      enabled: true
    test-sweep:
      enabled: true
    lint-sweep:
      enabled: false
    issue-to-pr:
      enabled: true
    approve-ready:
      enabled: true
    conflict-fix:
      enabled: true
  delivery:
    enabled: true
    value: true
    decisions: true
    compare: true
    people: true
    multiplier: 2.4
    rate: 120
    peopleRate: 110
    overheadPct: 20
    overheadRate: 105
    hoursPerMonth: 150
    manualDecisionWait: 6
    manualCycleDays: 4.5
    manualIssueDays: 3
    manualCardDays: 5
    roles:
      sse:
        enabled: true
        rate: 95
        mult: 2.4
      security:
        enabled: true
        rate: 110
        mult: 2
      qa:
        enabled: true
        rate: 70
        mult: 2.2
      devops:
        enabled: true
        rate: 90
        mult: 2
      reviewer:
        enabled: true
        rate: 95
        mult: 1.5
      planner:
        enabled: true
        rate: 120
        mult: 1.6
      writer:
        enabled: true
        rate: 60
        mult: 1.8
    kinds:
      toolcall:
        enabled: false
        minutes: 0
      mode:
        enabled: true
        minutes: 0.5
      goal:
        enabled: true
        minutes: 3
      plan:
        enabled: true
        minutes: 4
      triage:
        enabled: true
        minutes: 6
      merge:
        enabled: true
        minutes: 8
      other:
        enabled: true
        minutes: 2
    sources:
      checkpoint: true
      commit: true
      comment: true
      review: true
      chat: true
      notification: true
      admin: true
      pixcall: true
    companyDomain: acme.example
    idleGapMin: 5
    reviewMinPer100: 4

HCL (resource vulnetix_factory_settings)

# Every argument the kind supports. From config-schemas examples/FactorySettings/advanced.yaml.

resource "vulnetix_factory_settings" "default" {
  agents = {
    finalize_at           = 0.8
    max_attempts          = 0
    max_continuations     = 0
    max_cost_usd_per_item = 12.5
    max_iterations        = 0
    max_passes_per_item   = 0
    max_wall_minutes      = 0
  }
  approve = {
    sensitive_paths = [".github/workflows/**", "infra/**"]
  }
  audit = {
    calls         = true
    sign          = true
    weekly_report = true
  }
  autonomy = {
    claim_ttl_minutes  = 60
    concurrency        = 8
    default            = "suggest"
    max                = "auto_merge_low_risk"
    max_attempts       = 3
    no_host_ttl_hours  = 6
    parked_concurrency = 50
    plan_approval      = true
  }
  belai = {
    a_2_a = {
      show = true
    }
    ask_permission       = false
    auto_commit_per_task = true
    guardrails           = "on"
    mode                 = "goal"
    show_internal_work   = "decisions"
    tests = {
      on_fail  = "fix"
      post_end = "goal"
    }
  }
  budget = {
    alerts        = [50, 75, 90, 100]
    factory_share = 75
    month         = 50000000
    on_exceed     = "switch_to_pix_allocation"
  }
  crews = {
    lease = "30m"
  }
  defaults = {
    approve_ready = {
      enabled = true
    }
    ci_fix = {
      enabled = true
    }
    conflict_fix = {
      enabled = true
    }
    enabled = true
    issue_to_pr = {
      enabled = true
    }
    lint_sweep = {
      enabled = false
    }
    pr_review = {
      enabled = true
    }
    test_sweep = {
      enabled = true
    }
  }
  delivery = {
    company_domain  = "acme.example"
    compare         = true
    decisions       = true
    enabled         = true
    hours_per_month = 150
    idle_gap_min    = 5
    kinds = {
      goal = {
        enabled = true
        minutes = 3
      }
      merge = {
        enabled = true
        minutes = 8
      }
      mode = {
        enabled = true
        minutes = 0.5
      }
      other = {
        enabled = true
        minutes = 2
      }
      plan = {
        enabled = true
        minutes = 4
      }
      toolcall = {
        enabled = false
        minutes = 0
      }
      triage = {
        enabled = true
        minutes = 6
      }
    }
    manual_card_days     = 5
    manual_cycle_days    = 4.5
    manual_decision_wait = 6
    manual_issue_days    = 3
    multiplier           = 2.4
    overhead_pct         = 20
    overhead_rate        = 105
    people               = true
    people_rate          = 110
    rate                 = 120
    review_min_per_100   = 4
    roles = {
      devops = {
        enabled = true
        mult    = 2
        rate    = 90
      }
      planner = {
        enabled = true
        mult    = 1.6
        rate    = 120
      }
      qa = {
        enabled = true
        mult    = 2.2
        rate    = 70
      }
      reviewer = {
        enabled = true
        mult    = 1.5
        rate    = 95
      }
      security = {
        enabled = true
        mult    = 2
        rate    = 110
      }
      sse = {
        enabled = true
        mult    = 2.4
        rate    = 95
      }
      writer = {
        enabled = true
        mult    = 1.8
        rate    = 60
      }
    }
    sources = {
      admin        = true
      chat         = true
      checkpoint   = true
      comment      = true
      commit       = true
      notification = true
      pixcall      = true
      review       = true
    }
    value = true
  }
  factory = {
    fanout_cap = 6
  }
  forge = {
    branch_prefix  = "factory/"
    calls_per_hour = 5000
    check_runs     = false
    etag           = true
    poll = {
      fallback = "conditional_poll_10m"
    }
    pr_state  = "ready"
    protected = true
    quota = {
      factory_share             = 15
      on_exhausted              = "pause_live_reads"
      proactive_writes_per_hour = 60
      reserve                   = 20
    }
    read = {
      default = "posture_mirror"
    }
    stale = {
      alerts = "1h"
      checks = "2m"
      pulls  = "10m"
      repo   = "12h"
    }
  }
  hosts = {
    run_on          = "label:linux-large"
    run_on_fallback = "none"
  }
  jail = {
    enforcement_mode = "enforce"
  }
  kanban = {
    conflict_comment = true
    mode             = "all"
    opt_out_label    = "no-factory"
  }
  notify = {
    connector = "teams"
    events    = "escalations_holds_budget"
  }
  persistence = {
    export    = "manual"
    postgres  = "on"
    retention = "400d"
  }
  pix = {
    classifier     = "clef"
    egress_mode    = "deny_except_allow"
    extension_mode = "packs_only"
    jev_daily_cap  = 2000
    maintenance = [
      {
        days  = ["sun"]
        end   = "04:00"
        start = "02:00"
        tz    = "Australia/Melbourne"
      },
    ]
    reserve_percent = 20
    size            = "medium"
    version_policy  = "safest"
  }
  providers = {
    code = "pix-smart"
  }
  schedules = {
    blackout = [
      {
        from = {
          day  = "fri"
          time = "17:00"
        }
        label = "weekend"
        to = {
          day  = "mon"
          time = "08:00"
        }
      },
    ]
    missed = "run_once"
    tz     = "Australia/Melbourne"
  }
  scope = {
    archived     = true
    dependencies = false
    interest     = "scanned_or_pix"
    sync         = "1h"
  }
  signing = {
    auto_add    = true
    email       = "primary"
    mode        = "required"
    on_missing  = "readd"
    retire_days = "30"
    rotate_days = "180"
  }
  systemone = {
    below_threshold = "escalate_human"
    fallback        = "jev"
    min_confidence  = 0.85
    model           = "clef-flash"
    on_abstain      = "escalate_human"
    override        = true
    retention       = "full_400d"
  }
  tea = {
    publish = "on_release_tag"
  }
  vault = {
    grant = {
      entries = ["ve_ci_token"]
      mode    = "specific"
    }
    on_error = "pause_affected_workflows"
  }
  labels = {
    team = "platform"
  }
  annotations = {
    "vulnetix.com/owner" = "platform@acme.example"
  }
}

CLI (applies it)

export VULNETIX_CONFIG_TOKEN=vmt_...   # a config management token
vulnetix config apply -f - --manager gitops:acme/platform --auto-approve <<'EOF'
# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/FactorySettings.schema.json
apiVersion: vulnetix.com/v1
kind: FactorySettings
metadata:
  name: default
  labels:
    team: platform
  annotations:
    vulnetix.com/owner: platform@acme.example
spec:
  scope:
    interest: scanned_or_pix
    archived: true
    dependencies: false
    sync: 1h
  autonomy:
    max: auto_merge_low_risk
    default: suggest
    concurrency: 8
    claim_ttl_minutes: 60
    max_attempts: 3
    no_host_ttl_hours: 6
    parked_concurrency: 50
    plan_approval: true
  belai:
    mode: goal
    ask_permission: false
    guardrails: "on"
    tests:
      post_end: goal
      on_fail: fix
    show_internal_work: decisions
    auto_commit_per_task: true
    a2a:
      show: true
  factory:
    fanoutCap: 6
  systemone:
    model: clef-flash
    min_confidence: 0.85
    below_threshold: escalate_human
    on_abstain: escalate_human
    fallback: jev
    retention: full_400d
    override: true
  pix:
    classifier: clef
    jevDailyCap: 2000
    extensionMode: packs_only
    size: medium
    egressMode: deny_except_allow
    versionPolicy: safest
    maintenance:
      - days:
          - sun
        start: "02:00"
        end: "04:00"
        tz: Australia/Melbourne
    reservePercent: 20
  crews:
    lease: 30m
  agents:
    max_cost_usd_per_item: 12.5
    finalize_at: 0.8
    max_attempts: 0
    max_continuations: 0
    max_passes_per_item: 0
    max_wall_minutes: 0
    max_iterations: 0
  forge:
    branch_prefix: factory/
    pr_state: ready
    protected: true
    check_runs: false
    read:
      default: posture_mirror
    stale:
      repo: 12h
      pulls: 10m
      checks: 2m
      alerts: 1h
    poll:
      fallback: conditional_poll_10m
    etag: true
    quota:
      factory_share: 15
      reserve: 20
      on_exhausted: pause_live_reads
      proactive_writes_per_hour: 60
    calls_per_hour: 5000
  kanban:
    mode: all
    opt_out_label: no-factory
    conflict_comment: true
  signing:
    mode: required
    auto_add: true
    email: primary
    rotate_days: "180"
    retire_days: "30"
    on_missing: readd
  hosts:
    runOn: label:linux-large
    runOnFallback: none
  approve:
    sensitive_paths:
      - .github/workflows/**
      - infra/**
  tea:
    publish: on_release_tag
  jail:
    enforcementMode: enforce
  budget:
    factory_share: 75
    month: 50000000
    on_exceed: switch_to_pix_allocation
    alerts:
      - 50
      - 75
      - 90
      - 100
  providers:
    code: pix-smart
  vault:
    grant:
      mode: specific
      entries:
        - ve_ci_token
    on_error: pause_affected_workflows
  persistence:
    retention: 400d
    postgres: "on"
    export: manual
  schedules:
    tz: Australia/Melbourne
    blackout:
      - from:
          day: fri
          time: "17:00"
        to:
          day: mon
          time: "08:00"
        label: weekend
    missed: run_once
  audit:
    calls: true
    sign: true
    weekly_report: true
  notify:
    events: escalations_holds_budget
    connector: teams
  defaults:
    enabled: true
    pr-review:
      enabled: true
    ci-fix:
      enabled: true
    test-sweep:
      enabled: true
    lint-sweep:
      enabled: false
    issue-to-pr:
      enabled: true
    approve-ready:
      enabled: true
    conflict-fix:
      enabled: true
  delivery:
    enabled: true
    value: true
    decisions: true
    compare: true
    people: true
    multiplier: 2.4
    rate: 120
    peopleRate: 110
    overheadPct: 20
    overheadRate: 105
    hoursPerMonth: 150
    manualDecisionWait: 6
    manualCycleDays: 4.5
    manualIssueDays: 3
    manualCardDays: 5
    roles:
      sse:
        enabled: true
        rate: 95
        mult: 2.4
      security:
        enabled: true
        rate: 110
        mult: 2
      qa:
        enabled: true
        rate: 70
        mult: 2.2
      devops:
        enabled: true
        rate: 90
        mult: 2
      reviewer:
        enabled: true
        rate: 95
        mult: 1.5
      planner:
        enabled: true
        rate: 120
        mult: 1.6
      writer:
        enabled: true
        rate: 60
        mult: 1.8
    kinds:
      toolcall:
        enabled: false
        minutes: 0
      mode:
        enabled: true
        minutes: 0.5
      goal:
        enabled: true
        minutes: 3
      plan:
        enabled: true
        minutes: 4
      triage:
        enabled: true
        minutes: 6
      merge:
        enabled: true
        minutes: 8
      other:
        enabled: true
        minutes: 2
    sources:
      checkpoint: true
      commit: true
      comment: true
      review: true
      chat: true
      notification: true
      admin: true
      pixcall: true
    companyDomain: acme.example
    idleGapMin: 5
    reviewMinPer100: 4
EOF

Fields

Paths use dots for nesting and [] for the items of a list. Required means required whenever the parent object is present. A default is what the server uses when the field is left out.

Field Type Required Default Allowed values Description
apiVersion string yes exactly vulnetix.com/v1 The document format version. Every kind in this release is vulnetix.com/v1.
kind string yes exactly FactorySettings Always FactorySettings.
metadata object yes no other keys Metadata for a kind the tenant has exactly one of. The name is fixed to default.
metadata.name string yes exactly default; pattern ^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$ The object’s name, unique per kind within a tenant. It is the natural key: plan, apply, export and the Terraform provider all address an object by kind and name.
metadata.org string no format uuid The tenant (organization UUID) the document belongs to. When set, plan and apply refuse to run against any other tenant.
metadata.labels object no map of string to string (length 0 to 256); keys match ^[a-z0-9]([a-z0-9._/-]{0,61}[a-z0-9])?$ Free key/value labels. Stored with the object, never interpreted by the server.
metadata.annotations object no map of string to string (length 0 to 4096) Free key/value notes for people and tools, such as a ticket link.
spec object yes no other keys
spec.scope object no no other keys Which repositories of the managed organisations the factory looks at. The organisations themselves are FactoryManagedOrg documents.
spec.scope.interest string no any_signal any_signal, scanned_or_pix, watched_only Which repositories of a managed organisation count as of interest: any_signal (any signal at all), scanned_or_pix (scanned by Vulnetix or cloned in a Pix Sandbox) or watched_only (watched by a member).
spec.scope.archived boolean no false Include archived repositories.
spec.scope.dependencies boolean no false Include public dependency repositories that only appear through SBOM uploads.
spec.scope.sync string no 6h 6h, 1h, webhook_only How often the installation metadata sweep runs: every 6h, every 1h, or webhook_only (no sweep).
spec.autonomy object no no other keys How far the factory goes on its own, and how many runs it keeps going.
spec.autonomy.max string no draft_pr observe, suggest, draft_pr, auto_merge_low_risk The most autonomy any repository may run at. A repository’s own autonomy above it is lowered to it; the stored value is kept.
spec.autonomy.default string no draft_pr observe, suggest, draft_pr, auto_merge_low_risk The autonomy of a repository of a managed organisation that has no RepositorySettings of its own. auto_merge_low_risk is shown as approve when ready.
spec.autonomy.concurrency integer no 4 1 to 64 Runs of the tenant that may run at once.
spec.autonomy.claim_ttl_minutes integer no 60 1 to 1440 Minutes a started crew or worker dispatch may go without a session before the attempt fails card_unclaimed and is retried.
spec.autonomy.max_attempts integer no 3 1 to 10 Attempts at one workflow step before the run fails.
spec.autonomy.no_host_ttl_hours integer no 6 1 to 168 Hours a crew step may wait for a machine before the run ends no_host_timeout.
spec.autonomy.parked_concurrency integer no 50 1 to 1000 Runs of the tenant that may wait for a machine at once. They do not count against autonomy.concurrency.
spec.autonomy.plan_approval boolean no true Whether a belai:feature plan waits for a person to approve it.
spec.belai object no no other keys How crews the factory starts behave.
spec.belai.mode string no goal goal, agent, plan, auto The mode crews the factory starts run in.
spec.belai.ask_permission boolean no false Whether the workers and crews a workflow or schedule starts stop at permission asks.
spec.belai.guardrails string no on on, strict, off Belai guardrails for crews the factory starts. off is refused for worker crews.
spec.belai.tests object no no other keys
spec.belai.tests.post_end string no goal goal, goal_plan, session, off When tests run after a crew ends: after the goal, after the goal and its plan, after the session, or never.
spec.belai.tests.on_fail string no fix fix, diagnose, off What a crew does when those tests fail: fix them, diagnose only, or nothing.
spec.belai.show_internal_work string no decisions decisions, security, all, hidden Which internal work a transcript shows.
spec.belai.auto_commit_per_task boolean no true Commit after each task a crew finishes.
spec.belai.a2a object no no other keys
spec.belai.a2a.show boolean no true Whether transcripts show agent-to-agent rows (broadcasts, messages, replies, acknowledgements) by default. A viewer can override it.
spec.factory object no no other keys
spec.factory.fanoutCap integer no 6 1 to 50 Runs one delivery or sighting may start. Triggers past it, by priority, are skipped as fanout_cap.
spec.systemone object no no other keys System One, which scores the factory’s decisions.
spec.systemone.model string no clef-flash clef-flash, clef, jev, tev1 The System One adapter that scores decisions. Confidences are not comparable across adapters, so changing it records systemone.min_confidence against the new adapter.
spec.systemone.min_confidence number no 0.8 0 to 1 The confidence below which a System One decision is not taken on its own.
spec.systemone.below_threshold string no escalate_human escalate_human, route_to_fallback_model, take_safest_outcome, end_run What happens to a decision scored below systemone.min_confidence.
spec.systemone.on_abstain string no escalate_human escalate_human, retry_once_then_escalate, end_run What happens when System One abstains.
spec.systemone.fallback string no jev jev, pix-fast, none The model a decision is routed to under route_to_fallback_model.
spec.systemone.retention string no full_400d full_400d, hash_only, days_30 How System One decisions are kept: in full for 400 days, as hashes only, or for 30 days.
spec.systemone.override boolean no true Whether a person may override any System One decision.
spec.pix object no no other keys The Pix Sandbox the factory works in.
spec.pix.classifier string no clef clef, jev, tev1 The Pix Sandbox’s own classifier.
spec.pix.jevDailyCap integer no 2000 0 to 100000000 Calls per day to the jev classifier, shared with the Pix Sandbox.
spec.pix.extensionMode string no packs_only packs_only, any_indexed Which editor extensions a Pix Sandbox may install: curated packs only, or any indexed extension.
spec.pix.size string no medium small, medium, large The Pix Sandbox size. Takes effect at the sandbox’s next launch.
spec.pix.egressMode string no deny_except_allow deny_except_allow, allow_all_logged The Pix Sandbox egress mode. Takes effect at the sandbox’s next launch.
spec.pix.versionPolicy string no safest safest, stable, latest, rolling, pinned How a Pix Sandbox picks package versions. safest, stable, latest and rolling are the Safe Harbour picks. Takes effect at the sandbox’s next launch.
spec.pix.maintenance array of object no [] 0 to 100 items Weekly Pix Sandbox maintenance windows.
spec.pix.maintenance[].days array of string yes 1 to any items; each item: sun, mon, tue, wed, thu, fri, sat The days the window starts on.
spec.pix.maintenance[].start string yes pattern ^([01][0-9]|2[0-3]):[0-5][0-9]$ Start time, HH:MM, in tz.
spec.pix.maintenance[].end string yes pattern ^([01][0-9]|2[0-3]):[0-5][0-9]$ End time, HH:MM, in tz. An end before the start runs past midnight.
spec.pix.maintenance[].tz string yes length 1 to any The IANA time zone of start and end.
spec.pix.reservePercent integer no 20 0 to 100 Percent of the Pix allowance kept for interactive use.
spec.crews object no no other keys
spec.crews.lease string no 30m 15m, 30m, 2h How long a crew holds a handoff lease.
spec.agents object no no other keys Per-card limits for workers.
spec.agents.max_cost_usd_per_item number no 0 0 to 10000 Estimated cost in US dollars at which a worker’s claim on one card ends. 0 keeps each agent’s own limit.
spec.agents.finalize_at number no 0 0 to 0.95 Share of any per-card limit at which the worker is told to wrap up. A value under 0.5 is raised to 0.5; 0 keeps the agent’s own.
spec.agents.max_attempts integer no 0 0 to 10 Failed attempts at one stage before Belai blocks the card. 0 keeps the agent’s own. Not autonomy.max_attempts, which retries a workflow step.
spec.agents.max_continuations integer no 0 0 to 50 Times a card may be resumed after its budget ran out with progress made, before it is blocked for a person. 0 keeps the agent’s own.
spec.agents.max_passes_per_item integer no 0 0 to 1000 Goal passes per card. 0 keeps the agent’s own.
spec.agents.max_wall_minutes integer no 0 0 to 10080 Minutes per card. 0 keeps the agent’s own.
spec.agents.max_iterations integer no 0 0 to 400 Tool rounds per pass. 0 keeps the agent’s own.
spec.forge object no no other keys How the factory reads and writes GitHub and the other forges.
spec.forge.branch_prefix string no belai/K- pattern ^[A-Za-z0-9/_.-]{1,40}$ The prefix of branches the factory pushes.
spec.forge.pr_state string no draft draft, ready Whether the factory opens pull requests as drafts or ready for review.
spec.forge.protected boolean no true Never push to protected branches.
spec.forge.check_runs boolean no false Publish gate results as check runs. Needs the App permission checks: write on every managed installation.
spec.forge.read object no no other keys
spec.forge.read.default string no posture_mirror posture_mirror, s3_raw, live_api Where forge reads come from by default.
spec.forge.stale object no no other keys
spec.forge.stale.repo string no 6h pattern ^([0-9]+d|([0-9]+(\.[0-9]+)?(ms|s|m|h))+)$ How old repository data may be before it is read again. A duration from 30s to 7d, such as 30s, 5m, 6h or 2d.
spec.forge.stale.pulls string no 5m pattern ^([0-9]+d|([0-9]+(\.[0-9]+)?(ms|s|m|h))+)$ How old pull request data may be before it is read again. A duration from 30s to 7d, such as 30s, 5m, 6h or 2d.
spec.forge.stale.checks string no 2m pattern ^([0-9]+d|([0-9]+(\.[0-9]+)?(ms|s|m|h))+)$ How old check data may be before it is read again. A duration from 30s to 7d, such as 30s, 5m, 6h or 2d.
spec.forge.stale.alerts string no 1h pattern ^([0-9]+d|([0-9]+(\.[0-9]+)?(ms|s|m|h))+)$ How old alert data may be before it is read again. A duration from 30s to 7d, such as 30s, 5m, 6h or 2d.
spec.forge.poll object no no other keys
spec.forge.poll.fallback string no conditional_poll_10m conditional_poll_10m, none What a binding with no webhook does.
spec.forge.etag boolean no true Send If-None-Match on every live read.
spec.forge.quota object no no other keys
spec.forge.quota.factory_share integer no 10 0 to 100 Percent of the forge call budget the factory may use.
spec.forge.quota.reserve integer no 20 0 to 100 Percent of the forge call budget kept in reserve. At most 90, and with forge.quota.factory_share at most 100.
spec.forge.quota.on_exhausted string no pause_live_reads pause_live_reads, defer_to_next_window, escalate What the factory does when its share is used up.
spec.forge.quota.proactive_writes_per_hour integer no 60 0 to 5000 Most calls an installation makes in a clock hour for default workflows.
spec.forge.calls_per_hour integer no 5000 100 to 100000 The hourly call budget of a forge that sends no rate-limit headers, such as Gitea or Forgejo.
spec.kanban object no no other keys How kanban cards are mirrored to forge issues.
spec.kanban.mode string no all all, skip_review, off The default mode of a kanban binding: which cards are mirrored to forge issues. all: every card. skip_review: a card waits until it leaves Review. off: none.
spec.kanban.opt_out_label string no no-github pattern ^.{1,50}$ A card with this label is never mirrored to an issue.
spec.kanban.conflict_comment boolean no true Post a comment when the kanban sync finds a conflict.
spec.signing object no no other keys Commits a person makes from factory pages.
spec.signing.mode string no preferred required, preferred, off Whether commits a person makes from factory pages must be signed.
spec.signing.auto_add boolean no true Add a new signing key’s public key to the person’s GitHub account.
spec.signing.email string no primary primary, noreply, ask The address on a signed commit: the person’s primary address, their noreply address, or ask each time.
spec.signing.rotate_days string no 365 365, 180, 90, 0 Days before a signing key is rotated. 0 never rotates.
spec.signing.retire_days string no 30 30, 7, 0, -1 Days a replaced key stays on GitHub. 0 removes it right away; -1 leaves it there.
spec.signing.on_missing string no readd readd, ask What happens when GitHub no longer lists a key: add it again, or ask.
spec.hosts object no no other keys Where crew steps run.
spec.hosts.runOn string no auto pattern ^(auto|pix_sandbox|self_hosted|host:.+|label:.+)$ Where a crew node, a default or a scan that names no runOn runs: auto, pix_sandbox, self_hosted, host: or label:. It also orders the hosts a node’s own runOn admits.
spec.hosts.runOnFallback string no auto none, auto The fallback that goes with hosts.runOn. A node that sets its own runOnFallback keeps it.
spec.approve object no no other keys
spec.approve.sensitive_paths array of string no [] 0 to 100 items; each item: length 1 to 200 Path globs that stop an approval, besides the built-in list.
spec.tea object no no other keys
spec.tea.publish string no on_release_tag on_release_tag, on_merge_main, never When releases are published to TEA.
spec.jail object no no other keys
spec.jail.enforcementMode string no enforce enforce, warn Whether release jails block (enforce) or only report (warn).
spec.budget object no no other keys The factory’s token budget.
spec.budget.factory_share integer no 75 0 to 100 Percent of the Pix allowance the factory may use.
spec.budget.month integer no 30000000 0 to 1000000000000000 Tokens per month, all providers. This, budget.on_exceed and budget.alerts are the tenant’s Factory budget on the Budgets page.
spec.budget.on_exceed string no switch_to_pix_allocation pause_run, downgrade_to_fast, switch_to_pix_allocation, escalate_human, hard_stop What happens when the monthly budget is used up.
spec.budget.alerts array of integer no [50,80,100] 0 to 100 items; each item: 1 to 100 Percents of the monthly budget at which an alert is sent, ascending.
spec.providers object no no other keys
spec.providers.code string no pix-smart pattern ^(pix-smart|pix-fast|vault:[A-Za-z0-9._-]{1,64})$ The model for code work: pix-smart, pix-fast, or vault: for a model in the vault.
spec.vault object no no other keys Vault access from the Pix Sandbox.
spec.vault.grant object no {"mode":"all"} no other keys Which vault entries the Pix Sandbox may use.
spec.vault.grant.mode string yes specific, all, all_except all: every entry. specific: only those in entries. all_except: every entry except those in entries.
spec.vault.grant.entries array of string no 0 to 100 items; each item: length 1 to 64 Vault entry ids, for specific and all_except.
spec.vault.on_error string no pause_affected_workflows pause_affected_workflows, fall_back_to_pix What happens when a vault entry cannot be read.
spec.persistence object no no other keys Where factory records are kept and for how long.
spec.persistence.retention string no 400d 400d, 90d, 30d, forever How long factory records are kept.
spec.persistence.postgres string no on on, off Keep factory records in Postgres. off is accepted only while no workflow is published.
spec.persistence.export string no manual daily_jsonl_s3, manual How factory records are exported.
spec.schedules object no no other keys Schedules and blackout windows.
spec.schedules.tz string no UTC length 1 to any The IANA time zone of schedules and blackout windows.
spec.schedules.blackout array of object no [] 0 to 100 items Weekly windows in which no scheduled run starts, in schedules.tz.
spec.schedules.blackout[].from object yes no other keys When the window starts each week.
spec.schedules.blackout[].from.day string yes sun, mon, tue, wed, thu, fri, sat
spec.schedules.blackout[].from.time string yes pattern ^([01][0-9]|2[0-3]):[0-5][0-9]$ HH:MM.
spec.schedules.blackout[].to object yes no other keys When it ends.
spec.schedules.blackout[].to.day string yes sun, mon, tue, wed, thu, fri, sat
spec.schedules.blackout[].to.time string yes pattern ^([01][0-9]|2[0-3]):[0-5][0-9]$ HH:MM.
spec.schedules.blackout[].label string no length 0 to 200 A name for the window.
spec.schedules.missed string no run_once run_once, skip, run_all What happens to runs a schedule missed while the factory was paused or in a blackout.
spec.audit object no no other keys The audit trail.
spec.audit.calls boolean no true Log every model call with its input hash.
spec.audit.sign boolean no true Sign the decision ledger.
spec.audit.weekly_report boolean no true Send the weekly report.
spec.notify object no no other keys Notifications.
spec.notify.events string no escalations_holds_budget escalations_holds_budget, everything, escalations_only Which events are sent to notify.connector.
spec.notify.connector string no slack slack, teams, discord, google_chat, webhook, jira Where factory notifications go.
spec.defaults object no no other keys The default workflows. One switch per default, plus the master switch.
spec.defaults.enabled boolean no true The master switch of the default workflows. Off, no default is seeded and none starts.
spec.defaults.pr-review object no no other keys
spec.defaults.pr-review.enabled boolean no true Whether the pull request review default workflow is on for the tenant. A repository can still opt out with defaultsOff.
spec.defaults.ci-fix object no no other keys
spec.defaults.ci-fix.enabled boolean no true Whether the CI fix default workflow is on for the tenant. A repository can still opt out with defaultsOff.
spec.defaults.test-sweep object no no other keys
spec.defaults.test-sweep.enabled boolean no true Whether the test sweep default workflow is on for the tenant. A repository can still opt out with defaultsOff.
spec.defaults.lint-sweep object no no other keys
spec.defaults.lint-sweep.enabled boolean no true Whether the lint sweep default workflow is on for the tenant. A repository can still opt out with defaultsOff.
spec.defaults.issue-to-pr object no no other keys
spec.defaults.issue-to-pr.enabled boolean no true Whether the issue to pull request default workflow is on for the tenant. A repository can still opt out with defaultsOff.
spec.defaults.approve-ready object no no other keys
spec.defaults.approve-ready.enabled boolean no true Whether the approve when ready default workflow is on for the tenant. A repository can still opt out with defaultsOff.
spec.defaults.conflict-fix object no no other keys
spec.defaults.conflict-fix.enabled boolean no true Whether the merge conflict fix default workflow is on for the tenant. A repository can still opt out with defaultsOff.
spec.delivery object no no other keys The Delivery pages: how outcomes, value, decisions and people are measured and priced.
spec.delivery.enabled boolean no true The master switch of the Delivery pages. Off, nothing is computed.
spec.delivery.value boolean no true Price agent work by role.
spec.delivery.decisions boolean no true Price the decisions System One scored.
spec.delivery.compare boolean no true Show the hand-worked comparison, which adds the refinement and hand-off overhead.
spec.delivery.people boolean no true Show the People and Contributors pages.
spec.delivery.multiplier number no 2.4 0.5 to 10 Engineer hours per agent hour for agent work no role covers.
spec.delivery.rate number no 95 0 to 10000 US dollars per hour for agent work no role covers.
spec.delivery.peopleRate number no 110 0 to 10000 US dollars per hour for the hours people spent in the factory.
spec.delivery.overheadPct integer no 20 0 to 100 Refinement and hand-off overhead, as a percent of build and decision hours.
spec.delivery.overheadRate number no 105 0 to 10000 US dollars per hour for the overhead.
spec.delivery.hoursPerMonth number no 150 1 to 400 Productive hours per person-month.
spec.delivery.manualDecisionWait number no 6 0 to 720 Hours a team waits to decide, compared with the measured time.
spec.delivery.manualCycleDays number no 4.5 0 to 365 Days a team takes per pull request.
spec.delivery.manualIssueDays number no 3 0 to 365 Days a team takes per issue.
spec.delivery.manualCardDays number no 5 0 to 365 Days a team takes per card.
spec.delivery.roles object no no other keys Pricing per role.
spec.delivery.roles.sse object no no other keys
spec.delivery.roles.sse.enabled boolean no true Price agent work in the software engineer role.
spec.delivery.roles.sse.rate number no 95 0 to 10000 US dollars per hour for the software engineer role.
spec.delivery.roles.sse.mult number no 2.4 0.5 to 10 Engineer hours per agent hour for the software engineer role.
spec.delivery.roles.security object no no other keys
spec.delivery.roles.security.enabled boolean no true Price agent work in the security engineer role.
spec.delivery.roles.security.rate number no 110 0 to 10000 US dollars per hour for the security engineer role.
spec.delivery.roles.security.mult number no 2 0.5 to 10 Engineer hours per agent hour for the security engineer role.
spec.delivery.roles.qa object no no other keys
spec.delivery.roles.qa.enabled boolean no true Price agent work in the QA engineer role.
spec.delivery.roles.qa.rate number no 70 0 to 10000 US dollars per hour for the QA engineer role.
spec.delivery.roles.qa.mult number no 2.2 0.5 to 10 Engineer hours per agent hour for the QA engineer role.
spec.delivery.roles.devops object no no other keys
spec.delivery.roles.devops.enabled boolean no true Price agent work in the DevOps engineer role.
spec.delivery.roles.devops.rate number no 90 0 to 10000 US dollars per hour for the DevOps engineer role.
spec.delivery.roles.devops.mult number no 2 0.5 to 10 Engineer hours per agent hour for the DevOps engineer role.
spec.delivery.roles.reviewer object no no other keys
spec.delivery.roles.reviewer.enabled boolean no true Price agent work in the code reviewer role.
spec.delivery.roles.reviewer.rate number no 95 0 to 10000 US dollars per hour for the code reviewer role.
spec.delivery.roles.reviewer.mult number no 1.5 0.5 to 10 Engineer hours per agent hour for the code reviewer role.
spec.delivery.roles.planner object no no other keys
spec.delivery.roles.planner.enabled boolean no true Price agent work in the planner role.
spec.delivery.roles.planner.rate number no 120 0 to 10000 US dollars per hour for the planner role.
spec.delivery.roles.planner.mult number no 1.6 0.5 to 10 Engineer hours per agent hour for the planner role.
spec.delivery.roles.writer object no no other keys
spec.delivery.roles.writer.enabled boolean no true Price agent work in the technical writer role.
spec.delivery.roles.writer.rate number no 60 0 to 10000 US dollars per hour for the technical writer role.
spec.delivery.roles.writer.mult number no 1.8 0.5 to 10 Engineer hours per agent hour for the technical writer role.
spec.delivery.kinds object no no other keys Pricing per decision kind.
spec.delivery.kinds.toolcall object no no other keys
spec.delivery.kinds.toolcall.enabled boolean no false Count tool call guard rail decisions in the estimate. Tool calls are never in the estimate, whatever this switch says.
spec.delivery.kinds.toolcall.minutes number no 0 0 to 480 Minutes a person would take over one tool call guard rail decision.
spec.delivery.kinds.mode object no no other keys
spec.delivery.kinds.mode.enabled boolean no true Count mode change decisions in the estimate.
spec.delivery.kinds.mode.minutes number no 0.5 0 to 480 Minutes a person would take over one mode change decision.
spec.delivery.kinds.goal object no no other keys
spec.delivery.kinds.goal.enabled boolean no true Count goal decisions in the estimate.
spec.delivery.kinds.goal.minutes number no 3 0 to 480 Minutes a person would take over one goal decision.
spec.delivery.kinds.plan object no no other keys
spec.delivery.kinds.plan.enabled boolean no true Count plan decisions in the estimate.
spec.delivery.kinds.plan.minutes number no 4 0 to 480 Minutes a person would take over one plan decision.
spec.delivery.kinds.triage object no no other keys
spec.delivery.kinds.triage.enabled boolean no true Count triage decisions in the estimate.
spec.delivery.kinds.triage.minutes number no 6 0 to 480 Minutes a person would take over one triage decision.
spec.delivery.kinds.merge object no no other keys
spec.delivery.kinds.merge.enabled boolean no true Count merge decisions in the estimate.
spec.delivery.kinds.merge.minutes number no 8 0 to 480 Minutes a person would take over one merge decision.
spec.delivery.kinds.other object no no other keys
spec.delivery.kinds.other.enabled boolean no true Count other decisions in the estimate.
spec.delivery.kinds.other.minutes number no 2 0 to 480 Minutes a person would take over one other decision.
spec.delivery.sources object no no other keys Where to look for people.
spec.delivery.sources.checkpoint boolean no true Look for people in checkpoints.
spec.delivery.sources.commit boolean no true Look for people in commits.
spec.delivery.sources.comment boolean no true Look for people in comments.
spec.delivery.sources.review boolean no true Look for people in reviews.
spec.delivery.sources.chat boolean no true Look for people in chat messages.
spec.delivery.sources.notification boolean no true Look for people in notification actions.
spec.delivery.sources.admin boolean no true Look for people in board and admin actions.
spec.delivery.sources.pixcall boolean no true Look for people in Pix calls.
spec.delivery.companyDomain string no `` length 0 to 253 An email domain such as acme.example. A contributor on it, or on a subdomain, counts as internal. Empty for none.
spec.delivery.idleGapMin integer no 5 1 to 120 Minutes without an action that end a sitting.
spec.delivery.reviewMinPer100 number no 4 0 to 60 Minutes of reading per 100 changed lines of a review.

Applying this kind

  • Command. vulnetix config apply -f <file>; the CLI line above says from which release. Plan first with vulnetix config plan: it shows each object as create, update, delete or no change, with a planHash that apply then holds to. Apply writes in one transaction.
  • Manager. Each object records the manager that applied it (terraform, console or gitops:<repo>). --prune deletes only objects its own manager owns. See The manager and the config engine.
  • Status. revision. The phases the engine reports are explained under status phases.
  • Singleton. There is one per tenant, and its name is always default.

How apply treats it

  • A singleton. Every writable key of the factory settings table is a nested field (autonomy.max is spec.autonomy.max), except the keys other kinds own and the read-only keys (forge.polling.forbidden, firewall_enabled, systemone.min_confidence.adapter).
  • Replace semantics: a field left out is the default. Read returns only the settings that differ from the default, so exports are compact.
  • Validation is the console’s key table. Plan runs the read-only cross-key rules, including the forge.check_runs permission.
  • Apply writes through the same function as the settings page: a revision bump, the write-through hooks such as the tenant Factory budget, and one setting event and audit entry per changed key. The status reports revision.
  • Delete resets its keys to the defaults. The document stays.

Which kind owns which key

ScannerProfile owns the four security.* scanner keys, FactoryManagedOrg owns scope.orgs, NotificationDefaults owns notify.push.defaults, and FactorySettings owns the rest. A FactorySettings apply never writes a key it does not own, so the kinds cannot undo each other.

Export and import of the settings page

GET /v1/factory/settings?format=yaml|hcl|sh renders the FactorySettings, ScannerProfile and FactoryManagedOrg documents with the engine’s export. PUT /v1/factory/settings with Content-Type: application/yaml takes either these documents or the old flat export (read-only keys dropped, github.* renamed, the scope.orgs list turned into FactoryManagedOrg documents), then plans and applies them as manager console. ?dryRun=true returns the plan.

Terraform and OpenTofu

The resource is vulnetix_factory_settings in the vulnetix/resolve provider. Its arguments are the spec in snake case, beside name, labels and annotations from metadata. The Minimal and Advanced HCL are above. The provider’s own reference is vulnetix_factory_settings.

Import an object that already exists by its name (default):

# Import an existing FactorySettings by its name (metadata.name).
terraform import vulnetix_factory_settings.default default

Install, authentication and how state is read: Terraform and OpenTofu.

Check a file with vulnetix config validate -f <file>. See Validate documents. In an editor, start the file with the schema comment.

Edit this pageSources: config-schemas/schemas/FactorySettings.schema.json, config-schemas/schemas/common.schema.json, config-schemas/examples/FactorySettings/minimal.yaml, config-schemas/examples/FactorySettings/advanced.yaml, terraform-provider-resolve/examples/resources/vulnetix_factory_settings/minimal.tf, terraform-provider-resolve/examples/resources/vulnetix_factory_settings/advanced.tf, vdb-site/docs/platform-iac-engine.md, vdb-site/api/internal/handler/config_engine_kinds.go, vdb-site/api/internal/config/factorysettings.go, vdb-site/api/internal/handler/factory_settings_code.go
esc
↑ ↓ move↵ openSearches in your browser. A key like autonomy.max or a code like threshold_required jumps straight to it.