Skip to content

workspace.yaml agents

The software_delivery.agents block configures which agent client LumenFlow prefers, which agent names are considered part of the workspace roster, and which of those agents become mandatory for matching code paths.

Client configuration is descriptive, not authority. Every harness uses the versioned universal capability contract for methodology, WU operations, lifecycle, initiative planning, delegation, model/effort control, and application attestation. Model control, effort control, and application attestation remain separate outcomes, including model-only or effort-only host evidence. Missing or unknown capabilities fail safe; client names and host memory/cache cannot grant authority or synthesize a canonical brief. The release-evidence-indexed contract digest and lifecycle-issued brief/WU/workspace/HEAD evidence must all match before routing is verified.

software_delivery:
  agents:
    defaultClient: claude-code
    roster:
      - general-purpose
      - lumenflow-pm
      - test-engineer
      - code-reviewer
      - bug-triage
      - lumenflow-enforcer
      - initiative-architect
    mandatory:
      names: []
      triggers: {}
    clients:
      codex-cli:
        agentsDir: .agents/agents

Preferred client ID when a command needs an agent client and the caller did not pass one explicitly.

  • Type: string
  • Default: claude-code

The workspace-level list of agent names the orchestration surface should treat as valid. When you omit this field, LumenFlow uses the built-in framework roster:

  • general-purpose

  • lumenflow-pm

  • test-engineer

  • code-reviewer

  • bug-triage

  • lumenflow-enforcer

  • initiative-architect

  • Type: string[]

  • Default: the built-in agent roster above

Subset of agents.roster that may be enforced as mandatory when a matching trigger fires.

  • Type: string[]
  • Default: []

Maps mandatory agent names to glob patterns. If a WU touches a matching path, that agent becomes mandatory for the workflow surfaces that consume mandatory-agent rules.

  • Type: Record<string, string[]>
  • Default: {}

Example:

software_delivery:
  agents:
    roster:
      - custom-security-reviewer
    mandatory:
      names:
        - custom-security-reviewer
      triggers:
        custom-security-reviewer:
          - auth/**
          - supabase/migrations/**

Optional compatibility metadata for a project-owned client agent-definition directory. LumenFlow does not create, modify, or treat this directory as a managed surface; it remains separate from the workspace roster and canonical skills contract.

  • Type: string
  • Default: inherits the global directory default for that client

Declarative capability flags for a client, consumed by the idle-orchestrator push adapter port. This key previously carried a different, vendor capability-resolution shape (native_signal_hooks, settings_projection, enforcement_hooks, brief_renderer) that was retired: LumenFlow does not project settings, generate hooks, or gate brief rendering by client membership. It answers one narrow capability question — “does this client expose a native push channel this workspace can actually use to wake an idle session?” — and it is data-driven: setting the flag never by itself proves the channel is usable, it only tells LumenFlow to attempt a real per-host delivery instead of skipping straight to the always-available fallback.

  • Type: object
  • Default: { harnessPush: false } for every client, including the built-in ones. No client declares this on by default.
FieldTypeMeaning
harnessPushbooleanThis client declares a native push/notification channel to its own session. Selection is by this flag alone, never by client name. Default: false.
software_delivery:
  agents:
    clients:
      claude-code:
        capabilities:
          harnessPush: true

Declaring the flag is not the same as it working. Once harnessPush: true is declared, the push port attempts a REAL per-client delivery (vendor names live only in that adapter code, never in this config) and reports its own outcome. Currently, LumenFlow ships adapters for claude-code and codex-cli, and both report an explicit unsupported-on-host result rather than a silent fake success. An unknown/BYOK client id that sets the flag with no matching adapter gets the same honest treatment: an unsupported-on-host result naming the client id, never a thrown error and never a silent no-op. The durable JSONL wake-channel record mem-watch-fallback writes is the real delivery for every host today — orchestrate:monitor --watch or mem:watch is the prescribed orchestrator-side watcher regardless of this flag.

GitHub Actions runner label(s) for the generated .github/workflows/lumenflow-ci.yml enforcement job. lumenflow:enable and lumenflow:upgrade regenerate that workflow from a template whose default is ubuntu-latest; setting this field is what makes a self-hosted runner pool survive that regeneration instead of silently reverting to paid GitHub-hosted minutes on the next enable/upgrade.

  • Type: string | string[]
  • Default: unset (the generated workflow keeps the template’s ubuntu-latest default)
software_delivery:
  agents:
    lifecycle_enforcement:
      ci:
        runs_on:
          - self-hosted
          - Linux
          - X64
          - general-ci

agents.lifecycle_enforcement.ci.private_package_auth

Section titled “agents.lifecycle_enforcement.ci.private_package_auth”

Emit a registry auth step before dependency install in the generated .github/workflows/lumenflow-ci.yml, for consumers whose CI installs @hellmai/lumenflow-* from the licence-gated registry (<registry-url>). The step reads one repository secret, LUMENFLOW_CONSUMER_NPMRC, whose value is the full text of the consumer npmrc issued with the grant (the same file a developer selects with NPM_CONFIG_USERCONFIG locally), writes it to a runner-private file under runner.temp with umask 077, and the install step sets NPM_CONFIG_USERCONFIG to that file. No GitHub Packages, GITHUB_TOKEN, NODE_AUTH_TOKEN or npmjs token is involved; if the secret is unset the step prints a notice naming it and the install proceeds unauthenticated.

  • Type: boolean
  • Default: false
software_delivery:
  agents:
    lifecycle_enforcement:
      ci:
        private_package_auth: true

Only runs_on is modeled today. The rest of agents.lifecycle_enforcement (enabled, policy_version, integrity_manifest) is managed by lumenflow:enable/lumenflow:disable, not hand-edited.

Nested agent config merges with defaults instead of replacing the whole structure. For example, this partial override keeps the built-in roster and default client while only adding trigger rules:

software_delivery:
  agents:
    mandatory:
      triggers:
        custom-agent:
          - auth/**

Likewise, setting only mandatory.names no longer removes the default mandatory.triggers object.

Agent configuration does not grant lifecycle authority. Repository-owned delegators and the integrity manifest protect lifecycle evidence for every declared client, and only an enforced lumenflow:doctor state is certifying. Disabled and uninstalled consumers cannot claim lifecycle certification.

If your workspace previously only used:

software_delivery:
  agents:
    defaultClient: codex-cli

you do not need to change anything. That configuration still works.

Add the new fields only when you need them:

  1. Add agents.roster when you want to declare a custom or narrowed set of agent names.
  2. Add agents.mandatory.names when some of those agents should become enforceable.
  3. Add agents.mandatory.triggers when you want code-path-based mandatory-agent detection.
  4. Add agents.clients.<client>.agentsDir when a client should resolve agent definitions from a non-default directory.
  5. Add agents.clients.<client>.capabilities.harnessPush only when you want the idle-orchestrator push port to attempt a real per-host delivery for that client instead of going straight to the always-available mem-watch-fallback adapter. Omitting it (the default for every client) never loses delivery — the fallback adapter already covers every host.

The authoritative schema enforces two cross-field rules:

  • Every name in agents.mandatory.names must also appear in agents.roster.
  • Every key in agents.mandatory.triggers must also appear in agents.mandatory.names.

Those rules keep the roster, mandatory list, and trigger map aligned as you customize the workspace.