Platform

Platform overviewArchitectureWorkflow orchestrationGitOps configurationGovernance and AAAAI and MCPKnowledge and contextRuntime and executionEvidence and monitoring

Use cases

All use casesProduction incidentRelease preparationHotfix to productionSecurity scan triage
Why NopsAIIntegrationsSecurity

Resources

All resourcesAI agent governanceMCP governanceMCP securitySelf-hosted platforms
PricingGitHub

Company

How a run worksAboutContactBook a demo

AI steps

Replacing a script with a goal, and choosing the model that pursues it.

ReferenceAutomation authorDeveloper

Key points

  • goal is the LLM-backed step mode. It cannot be combined with script, tasks, include, or approval.
  • llm_enabled defaults to true. Setting it to false bans output.items, every step condition, every goal, and any script carrying blocking guardrail or policy knowledge context.
  • model resolves in order: task, step, pipeline, configured default.
  • The named model must be configured and allowed in the run scope; AAA decides whether the caller may use it.
  • A goal runs inside the per-run agent. There is no always-on LLM service, and the agent calls the provider the resolved model names.
  • A task can carry a goal too, so one step can mix deterministic and model-driven work across its tasks.

Examples

What this page addsyaml
llm_enabled: true
model: reasoning-large

  - name: release-notes
    depends_on: [publish]
    goal: Read the commits since the last tag and write release notes to /workspace/NOTES.md.
    model: reasoning-large
Pipeline so faryaml
name: release-service
description: Build, verify, and publish the payments service.
container_image: alpine:3.20
working_directory: /workspace
timeout: 45m
display_option: list
llm_enabled: true
model: reasoning-large
variables:
  - RELEASE_CHANNEL
  - platform/shared:ARTIFACT_BUCKET
steps:
  - name: build
    script: |
      make build
      echo "1.0.$(date +%s)" > /nopsai/outputs/BUILD_TAG
    outputs:
      - name: BUILD_TAG

  - name: verify
    image: golang:1.24
    depends_on: [build]
    runtime_pool: ci
    volumes:
      - build-cache:/root/.cache
    script: |
      go vet ./...
      go test ./...

  - name: checks
    depends_on: [verify]
    tasks:
      - name: licenses
        ignore_failure: true
        script: |
          ./scripts/license-check.sh
      - name: sbom
        script: |
          ./scripts/sbom.sh > /workspace/sbom.json
          sha256sum /workspace/sbom.json | cut -d' ' -f1 > /nopsai/outputs/SBOM_DIGEST
        outputs:
          - name: SBOM_DIGEST
      - name: risk-review
        depends_on: [checks.sbom]
        goal: Review the changed files and list the risks this release carries.
        model: reasoning-large
      - name: report
        depends_on: [checks.licenses, checks.sbom]
        variables:
          SBOM_DIGEST: $steps.checks.sbom.outputs.SBOM_DIGEST
        script: |
          echo "checks complete"
          echo "sbom $SBOM_DIGEST"

  - name: package
    depends_on: [checks]
    secrets:
      - REGISTRY_TOKEN
      - platform/shared:SIGNING_KEY
    variables:
      BUILD_TAG: $steps.build.outputs.BUILD_TAG
    script: |
      ./scripts/package.sh "$BUILD_TAG"
      echo "channel $RELEASE_CHANNEL, bucket $ARTIFACT_BUCKET"
      ./scripts/mint-token.sh > /nopsai/outputs/PUBLISH_TOKEN
      ./scripts/sign.sh --key "$SIGNING_KEY" --token "$REGISTRY_TOKEN"
    outputs:
      - name: PUBLISH_TOKEN
        sensitive: true

  - name: announce
    depends_on: [package]
    condition: Only run when the release channel is stable.
    ignore_failure: true
    script: |
      ./scripts/announce.sh

  - name: production-gate
    depends_on: [package]
    approval:
      type: production-release
      teams:
        - platform/sre
      allow_self_approval: false
      timeout: 24h

  - name: publish
    depends_on: [production-gate]
    script: |
      ./scripts/promote.sh

  - name: release-notes
    depends_on: [publish]
    goal: Read the commits since the last tag and write release notes to /workspace/NOTES.md.
    model: reasoning-large
Result

One model-driven task inside checks and one model-driven step after publish, both resolving to reasoning-large.

Rejected: a goal with the LLM disabledyaml
llm_enabled: false
steps:
  - name: release-notes
    goal: Write the release notes.
Result

Rejected: goal requires an LLM-enabled pipeline.

Field reference

llm_enabledpipelinebooleanOptionaltrue

Set false to declare a script-only pipeline. Validation then rejects every LLM-backed construct.

Example

llm_enabled: false

Rules
  • With false, the pipeline cannot define output.items, any step condition, any goal, or a script that carries blocking guardrail/policy knowledge context.
Evidence

services/nopsai/pkg/validation/pipeline.go

modelpipelinestringOptionalConfigured default model

Default provider/model profile for conditions, goals, and final outputs.

Example

model: reasoning-large

Rules
  • The profile must be configured and allowed in the run scope.
Overridden by

steps[].model, tasks[].model, output.model, output.items[].model

Permission

AAA still decides whether the original caller may use the selected profile.

Evidence

services/nopsai/pkg/validation/pipeline.go

steps[].goalstep modestringConditionalNone

Single LLM-backed goal for the step.

Example

goal: Update the changelog with every merged pull request since the last tag.

Rules
  • Rejected when llm_enabled: false.
  • Cannot be combined with script or tasks.
steps[].modelstepstringOptionalPipeline `model`

Model-client override applied to the step condition and to tasks that do not set their own.

Example

model: fast-small

Overridden by

tasks[].model

tasks[].goaltaskstringConditionalNone

LLM-backed task goal. Mutually exclusive with script; exactly one of the two is required.

Example

goal: Summarize the failing tests and propose a fix.

Rules
  • Rejected when llm_enabled: false.
Evidence

services/nopsai/pkg/validation/pipeline.go

tasks[].modeltaskstringOptionalStep `model`, then pipeline, then configured default

Most specific model-client override for this task.

Example

model: reasoning-large

How it works

A goal is a statement of intent with a definition of done, not a prompt fragment. "Read the commits since the last tag and write release notes to /workspace/NOTES.md" tells the agent what to read, what to produce, and where to put it.

The workspace is the interface. A goal step reads and writes the same /workspace the script steps use, which is why an LLM step can sit in the middle of a deterministic pipeline without special plumbing.

Model selection is a governance decision as much as a quality one. Naming a model in the pipeline makes it reviewable, and the scope check makes it enforceable.

Implementation evidence

  • services/nopsai/pkg/validation/pipeline.go

    Rules the validator enforces on this directive set.

  • doc/llm-model-selection.md

    Model resolution and provider selection.