Modifying CLI Output Schema

SkillDev tools

Adding or modifying Golem CLI StructuredOutput implementations, command-output.schema.json, or DTO-backed output schema generators.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Modifying CLI Output Schema skill

What this skill tells your AI

The instructions your AI receives, as published by golemcloud/golem in .agents/skills/modifying-cli-output-schema/SKILL.md and read by ahel’s review.

Use this skill when changing structured output from golem-cli, including:

  • adding or modifying a StructuredOutput implementation;
  • changing a DTO/view used by structured CLI output;
  • editing cli/golem-cli/command-output-schema/command-output.schema.json;
  • changing schema tests or arbitrary generators under cli/golem-cli/src/model/cli_output/.

This is different from the application manifest schema under cli/schema.golem.cloud/app/golem/. For manifest schema version changes, use modifying-cli-manifest-schema instead.

Core Rules

  1. Keep the public $type discriminator model. Every structured output document must have the right $type value for the current contract.
  2. $type values are semantic output identifiers. Prefer command-like names when there is a direct command correspondence (for example agent.invoke or component.manifest-trace). For streaming outputs, use the command family plus the streamed resource or event type (for example agent.stream for stream events and agent.oplog for oplog entries). Use domain/subdocument names when the output is part of a larger command flow (for example deploy.diff). Do not add redundant .result or .event suffixes. If a contract intentionally changes a $type, update every in-tree consumer directly; do not preserve the old value through aliases or duplicate output variants.
  3. Keep machine-readable structured output on stdout and human logs, prompts, progress, and diagnostics on stderr.
  4. Prefer typed schema definitions over JsonValue. Use generic JSON only when the payload is semantically arbitrary or cannot be related in JSON Schema draft-07.
  5. Match serde's actual serialized shape, not the Rust type shape you expect. Tagged enums, flattened enum payloads, skipped fields, and custom serializers are common drift sources.
  6. For exact object schemas, set additionalProperties: false and keep required entries aligned with properties.
  7. Every top-level output definition listed in x-golem-cli-output-types must include description, x-golem-output-mode, and x-golem-command metadata. Use x-golem-output-mode: "single" for normal one-document commands and "stream" for commands that emit one document per event or entry. Use "multi-document" for finite command-bounded outputs where multiple $types may appear conditionally during one command run. Use x-golem-command for the primary or representative emitting command, and add x-golem-commands when an output type is emitted by multiple public commands.

Important Files

  • cli/golem-cli/command-output-schema/command-output.schema.json — public handwritten CLI output schema.
  • cli/golem-cli/src/model/cli_output/mod.rsStructuredOutput, schema loading, focused-schema support, and serialization helpers.
  • cli/golem-cli/src/model/cli_output/tests.rs — registry checks, schema tests, and DTO-backed arbitrary generators.
  • cli/golem-cli/src/model/text/** — many structured output view types.
  • cli/golem-cli/src/model/** — CLI DTO/view models used by structured output.
  • golem output-schema — top-level command that prints the raw schema document for automated agents and tooling. --types prints only output type names; repeated --type <TYPE> prints a pruned schema containing only selected output definitions and recursively referenced definitions.
  • Makefile.tomlcheck-cli-output-schema and update-cli-output-schema-summary tasks.

Generator Rules

Property-based schema examples should construct real Rust DTO/view values and serialize them through to_structured_output_value or to_structured_output_value_masked when the output contains maskable data.

Do not hand-build full output JSON documents in generators. Hand-built JSON is acceptable only for:

  • minimal negative schema tests;
  • intentionally arbitrary serde_json::Value leaves;
  • small helper payloads that are themselves semantically JSON values.

When schema coverage is expanded, expand the generator too. The generator should exercise meaningful variants and nested shapes, not just the empty/default case. If a generator reveals schema drift, inspect the serialized DTO and fix the schema or the DTO intentionally.

Accepted Generic JSON Leaves

These generic areas are intentional unless the task explicitly says otherwise:

  • ValueAndTypeJson.value: draft-07 cannot validate it relationally against sibling typ.
  • AgentConfigEntryDto.value: this is NormalizedJsonValue and is semantically arbitrary JSON.
  • Manifest config JSON leaves inside typed manifest trace output.
  • Snapshot JSON payload leaves inside typed agent.oplog entries.
  • Raw/default/display secret values: valid shape depends on secret type and display context.

Oplog Coverage

agent.oplog uses the public oplog DTOs (PublicOplogEntry and nested public types) from golem-common. The CLI output schema models the public oplog entry union explicitly, and the output generator builds a single AgentOplogEntryView sample containing all public oplog variants plus nested invocation, snapshot, retry policy, span, plugin, and update shapes.

When changing public oplog entries, update both the PublicOplogEntry schema family and the deterministic AgentOplogEntryView sample in cli_output/tests.rs. Keep ValueAndTypeJson.value and JSON snapshot payload leaves generic unless custom relational validation is introduced.

Workflow

  1. Identify the affected output kind and StructuredOutput type.
  2. Update the Rust DTO/view model if needed.
  3. Update command-output.schema.json to match actual serde output.
  4. Add or update top-level output metadata (description, x-golem-output-mode, x-golem-command, and optionally x-golem-commands) for affected schema definitions.
  5. Add or improve the generator in cli_output/tests.rs using real DTO/view values.
  6. Run focused schema tests and inspect failures as DTO/schema drift.
  7. Check whether user-facing skills under golem-skills/skills need updates when CLI output field names, $type names, or examples change.
  8. Check whether golem-skills/tests needs updates when output field names, $type names, JSON formatting, or invoke JSON unwrapping changes.
  9. Verify golem output-schema still prints the current raw schema document, golem output-schema --types lists compact type names, and focused schemas such as golem output-schema --type agent.invoke remain valid and pruned.
  10. Regenerate the local output summary when the registry or output types change.

User-Facing Skill Impact

CLI structured output changes can make embedded user-facing skills stale. Always search golem-skills/skills when changing:

  • machine-readable CLI field names, such as resultJson / resultsJson;
  • $type naming conventions;
  • examples showing --format json, --format yaml, or structured output;
  • command names or flags used in skill instructions.

If any files under golem-skills/skills change, regenerate the generated How-To Guide docs before finishing:

cargo make generate-docs-skills

CI rejects drift via cargo make check-docs-skills.

Golem Skill Harness Impact

CLI structured output changes can break generated-application skill tests under golem-skills/tests, especially the harness code that invokes golem-cli and unwraps JSON output.

When public CLI output changes, inspect and update affected files under:

  • golem-skills/tests/harness/src/;
  • golem-skills/tests/harness/tests/;
  • golem-skills/tests/harness/scenarios/.

The full scenario suite can require credentials, services, and significant time, and is normally run later in PR/CI. Locally, run focused harness unit/build checks only when harness TypeScript code or fixtures changed:

cd golem-skills/tests/harness
npm run build
npm test

Validation

Run these for CLI output schema/generator changes:

cargo fmt --package golem-cli -- --check
cargo test -p golem-cli cli_output_schema_ --lib -- --report-time
cargo make check-cli-output-schema
cargo make update-cli-output-schema-summary
cargo check -p golem-cli

Smoke-check schema exposure when the command or schema file changed:

cargo run -p golem-cli -- output-schema
cargo run -p golem-cli -- output-schema --types
cargo run -p golem-cli -- output-schema --type agent.invoke

If arbitrary generators changed, rerun the generated-example prop test a few times:

cargo test -p golem-cli cli_output_schema_accepts_registered_generated_examples --lib -- --report-time

Remove transient cli/golem-cli/proptest-regressions/ files created by failing local generator runs unless the project intentionally wants to commit that regression seed.

Common Drift Sources

  • Nullable fields that are Option<T> in DTOs but schema forgot null.
  • Enum case casing (kebab-case, camelCase, or Rust variant names).
  • Internally tagged enum payloads that flatten fields into the same object.
  • Custom serializers such as manifest trace appliedLayers.
  • skip_serializing_if fields that should not be required.
  • New nested DTO variants not covered by generators.
  • EnvironmentSetupPlanView serializes the precomputed EnvironmentSetupPlan.display. That display must be constructed with the active MaskingConfig; do not build this view from unmasked environment setup display data.

Checklist

  1. $type is registered in both source and schema and matches the current contract.
  2. $type is suffixless and semantically named; it is command-like when that is accurate, but not assumed to be a literal CLI command path.
  3. Schema matches actual serde_json::to_value output.
  4. Top-level schema definition has description, x-golem-output-mode, and x-golem-command metadata; reused types have x-golem-commands when useful.
  5. Output generator constructs real DTO/view values.
  6. Important enum and nested variants are covered by examples or generators.
  7. User-facing skills under golem-skills/skills have been checked when public output changed.
  8. golem-skills/tests impact has been checked when public output changed.
  9. Generated docs from user-facing skills were regenerated if golem-skills/skills changed.
  10. golem output-schema prints the current raw schema document.
  11. golem output-schema --types and --type <TYPE> expose compact discovery and pruned schemas for coding agents.
  12. Remaining JsonValue leaves are documented and intentional.
  13. Focused schema tests, check task, summary update, and cargo check -p golem-cli pass.

Signals

GitHub stars
2k
Forks
212
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
modifying-cli-output-schema
Source
github.com/golemcloud/golem