Use CUE behind AOS-owned Ward profile validation and composition #523

Closed
opened 2026-07-14 09:59:37 +00:00 by coilyco-ops · 6 comments
Member

Decision

Go, from coilysiren/inbox#211.

Use CUE as the validation/composition engine behind AOS-owned Ward profile assets after Ward consumes typed profile data. This keeps YAML/operator-facing assets in AOS and explicitly does not create a ward-profile repo.

Scope

  • Add or propose a CUE-backed validation/composition path for the Ward profile assets owned by AOS.
  • Keep generated or rendered outputs public-safe and compatible with Ward's typed ProfileProvider seam.
  • Document how CUE, YAML, and any rendered artifacts relate so operators do not treat CUE as a new required hand-authored language.
  • Gate this behind the Ward typed profile seam so AOS does not become a downward runtime config dependency.

Non-goals

  • Do not create a ward-profile repository.
  • Do not add an operator-facing advanced.profile_ref contract.
  • Do not make Ward fetch live config from AOS at runtime.

Parent: coilysiren/inbox#211.
Related: coilyco-flight-deck/agentic-os#516, coilyco-flight-deck/ward#1247.

## Decision Go, from coilysiren/inbox#211. Use CUE as the validation/composition engine behind AOS-owned Ward profile assets after Ward consumes typed profile data. This keeps YAML/operator-facing assets in AOS and explicitly does not create a ward-profile repo. ## Scope - Add or propose a CUE-backed validation/composition path for the Ward profile assets owned by AOS. - Keep generated or rendered outputs public-safe and compatible with Ward's typed ProfileProvider seam. - Document how CUE, YAML, and any rendered artifacts relate so operators do not treat CUE as a new required hand-authored language. - Gate this behind the Ward typed profile seam so AOS does not become a downward runtime config dependency. ## Non-goals - Do not create a ward-profile repository. - Do not add an operator-facing advanced.profile_ref contract. - Do not make Ward fetch live config from AOS at runtime. Parent: coilysiren/inbox#211. Related: coilyco-flight-deck/agentic-os#516, coilyco-flight-deck/ward#1247.
Author
Member

WARDED_WORKFLOW: reservation-held

reservation details

Holder: launch intent for container engineer-codex-agentic-os-523 on host kais-macbook-pro-2.local.

Accepted by ward agent --harness codex (reserved 2026-07-14T10:05:31Z). Concurrent ward agent runs are blocked until this intent becomes visible or the intent is released. The stale-intent fallback is still TTL-bounded (3h TTL). --override-reservation overrides.

Do not comment on or edit this issue to steer the run while it is reserved. The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a new issue, dispatched fresh. That is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494).

run seed context — what this run is carrying (ward#609)
  • Resolved: coilyco-flight-deck/agentic-os#523 · branch issue-523 · harness codex · workflow pull-request-and-merge
  • Run: engineer-codex-agentic-os-523 · ward v0.675.0 · dispatched 2026-07-14T10:05:28Z
  • Comment thread: 0 included in the pre-flight read, 0 stripped (ward's own automated comments).

Static container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.675.0).

— Codex, via ward agent

<!-- ward-agent-reservation --> WARDED_WORKFLOW: reservation-held <details><summary>reservation details</summary> Holder: launch intent for container `engineer-codex-agentic-os-523` on host `kais-macbook-pro-2.local`. Accepted by `ward agent --harness codex` (reserved 2026-07-14T10:05:31Z). Concurrent `ward agent` runs are blocked until this intent becomes visible or the intent is released. The stale-intent fallback is still TTL-bounded (3h TTL). `--override-reservation` overrides. **Do not comment on or edit this issue to steer the run while it is reserved.** The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a **new issue, dispatched fresh**. That is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494). <details><summary>run seed context — what this run is carrying (ward#609)</summary> - **Resolved:** `coilyco-flight-deck/agentic-os#523` · branch `issue-523` · harness `codex` · workflow `pull-request-and-merge` - **Run:** `engineer-codex-agentic-os-523` · ward `v0.675.0` · dispatched `2026-07-14T10:05:28Z` - **Comment thread:** 0 included in the pre-flight read, 0 stripped (ward's own automated comments). Static container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.675.0). </details> </details> <!-- ward-agent-signature --> — Codex, via `ward agent`
Author
Member

🔎 ward agent advisor

ward agent advisor --harness codex ran a one-shot standard research pass on this question:

Read the issue title, body, and comment thread below as the research brief. Identify the decisions, options, open questions, and risks, then give a clear advisory recommendation that can be posted back on the issue.


Recommendation

Proceed in AOS, but make this a build-time validation and rendering path, not a Ward runtime dependency. The first slice should add the profile asset structure, CUE schema/composition files, a validation command, and docs that say operators edit YAML. CUE should be described as the internal validator/compiler behind that YAML, not as the new hand-authored profile language.

Context read

  • ward#1247 is closed and landed the internal ProfileProvider seam. In the current Ward tree it returns typed smart defaults, fleet, topology, and agent role data, but the default provider still reads the existing KDL-backed configSource.
  • agentic-os#516 is closed and landed docs/ward-profile-assets.md. AOS is now documented as the home for profile assets that survive the typed seam.
  • The current AOS .ward/ tree has guardfiles, roles, repos, workflow, and scripts. It does not yet have .ward/profiles/.
  • ward#1265 is open downstream and says the embedded profile/KDL fallback should live for one release train only after the typed profile path and AOS assets are available.
  • The current AOS release packaging for ward-specs-<tag>.tar.gz only includes top-level files under .ward/, not nested profile directories. Profile assets will need an explicit packaging decision.
  • The current container does not have a cue binary, so toolchain plumbing is part of the work if validation becomes a normal gate.

Decisions already made

  • Use CUE for validation/composition behind AOS-owned Ward profile assets.
  • Keep YAML/operator-facing assets in AOS.
  • Do not create a ward-profile repo.
  • Do not add an operator-facing advanced.profile_ref contract.
  • Do not make Ward fetch live config from AOS at runtime.
  • Keep the work gated behind Ward's typed profile seam.

Preferred shape

  • Add .ward/profiles/ as the source home described by docs/ward-profile-assets.md.
  • Put hand-authored operator inputs in YAML, for example .ward/profiles/<family>/*.yaml.
  • Put CUE schema and composition internals in a clearly internal subpath, for example .ward/profiles/cue/ or .ward/profiles/_cue/.
  • Put generated output in an explicit render directory only after Ward has a concrete typed input contract, for example .ward/profiles/rendered/. Mark it generated and add a drift check.
  • Add a ward verb in AOS such as ward exec ward-profile-validate or ward exec profile-assets that runs cue vet and, when needed, cue export. CUE's own docs support this split: cue vet validates data and cue export produces concrete JSON/YAML for tools.
  • Update docs/ward-profile-assets.md to define the three layers: YAML is operator source, CUE is validation/composition machinery, rendered files are generated provider inputs.
  • Do not wire Ward to evaluate .cue files at launch. Ward should consume typed data or pinned release artifacts, not import AOS source state live.

Options considered

  • Preferred: YAML source plus CUE validation/composition in AOS, with rendered typed artifacts once Ward defines the serialized provider input. This matches the issue decision and keeps CUE behind the curtain.
  • Minimal first slice: add only schema, sample YAML, docs, and validation. Defer rendered artifacts until Ward exposes the exact file shape. This is safe if the typed provider serialization is not ready.
  • Ward-integrated CUE provider: not recommended for this issue. It would move CUE into Ward runtime and blur the AOS/Ward ownership line.
  • CUE as the hand-authored source language: reject. It violates the operator-facing YAML decision.
  • New ward-profile repo: reject. It is explicitly denied by the issue and parent roadmap.

Open questions

  • What is Ward's concrete serialized typed provider input? The current seam is typed internally, but the implementation still adapts KDL-backed sources. AOS should not guess whether the durable render is one aggregate file or one file per provider method.
  • Should profile artifacts ship inside the existing ward-specs release tarball, or as a separate ward-profiles-<tag>.tar.gz asset? The current tarball logic will miss nested .ward/profiles/ files unless it is deliberately changed.
  • Should rendered files be committed, generated only in CI, or attached only as release artifacts? My bias is to commit generated renders only when Ward consumes them from source or tests need drift visibility. Otherwise attach a deterministic release asset.
  • Where should the CUE toolchain be pinned? Options are dev-base, a Go helper, or CI-local go run cuelang.org/go/cmd/cue@<version>. If this becomes pre-commit or CI, dev-base should carry the binary.
  • What overlay precedence should CUE enforce across profile families? This should be documented before multiple families exist.

Risks

  • CUE could accidentally become a second operator language. Avoid this with docs, path naming, and examples that only ask operators to edit YAML.
  • AOS could become a downward runtime dependency if Ward fetches .cue or YAML directly from an AOS checkout. Avoid this by using pinned release artifacts or build-time renders.
  • Generated artifact drift can make Ward consume stale profile data. Add a drift check once renders exist.
  • The CUE schema can drift from Ward's private Go types because Ward's current provider returns unexported command-package types. The render contract needs to be explicit before AOS locks a schema.
  • The existing release packaging does not include nested profile paths. Without a packaging update, the assets can pass locally but never reach Ward's pinned release inputs.
  • A hard pre-commit dependency on cue will fail in current containers until the binary is installed or the hook runs through a pinned helper.

Advisory close

The next engineering pass should stay in coilyco-flight-deck/agentic-os: create the .ward/profiles/ source layout, add CUE schema/validation scaffolding, add a ward-wrapped validation command, and update the profile-assets doc. It should not change Ward runtime behavior yet unless Ward already has a concrete typed file contract ready. If that contract is still absent, the AOS issue can still land as the validated source and documentation base, with the render target left as a named dependency on the Ward typed provider input.


Researched and posted automatically by ward agent advisor --harness codex (ward#179). This is one-shot research, not a carried change - verify before acting on it.

— Codex, via ward agent

### 🔎 ward agent advisor `ward agent advisor --harness codex` ran a one-shot **standard** research pass on this question: > Read the issue title, body, and comment thread below as the research brief. Identify the decisions, options, open questions, and risks, then give a clear advisory recommendation that can be posted back on the issue. --- **Recommendation** Proceed in AOS, but make this a build-time validation and rendering path, not a Ward runtime dependency. The first slice should add the profile asset structure, CUE schema/composition files, a validation command, and docs that say operators edit YAML. CUE should be described as the internal validator/compiler behind that YAML, not as the new hand-authored profile language. **Context read** * `ward#1247` is closed and landed the internal `ProfileProvider` seam. In the current Ward tree it returns typed smart defaults, fleet, topology, and agent role data, but the default provider still reads the existing KDL-backed `configSource`. * `agentic-os#516` is closed and landed `docs/ward-profile-assets.md`. AOS is now documented as the home for profile assets that survive the typed seam. * The current AOS `.ward/` tree has guardfiles, roles, repos, workflow, and scripts. It does not yet have `.ward/profiles/`. * `ward#1265` is open downstream and says the embedded profile/KDL fallback should live for one release train only after the typed profile path and AOS assets are available. * The current AOS release packaging for `ward-specs-<tag>.tar.gz` only includes top-level files under `.ward/`, not nested profile directories. Profile assets will need an explicit packaging decision. * The current container does not have a `cue` binary, so toolchain plumbing is part of the work if validation becomes a normal gate. **Decisions already made** * Use CUE for validation/composition behind AOS-owned Ward profile assets. * Keep YAML/operator-facing assets in AOS. * Do not create a `ward-profile` repo. * Do not add an operator-facing `advanced.profile_ref` contract. * Do not make Ward fetch live config from AOS at runtime. * Keep the work gated behind Ward's typed profile seam. **Preferred shape** * Add `.ward/profiles/` as the source home described by `docs/ward-profile-assets.md`. * Put hand-authored operator inputs in YAML, for example `.ward/profiles/<family>/*.yaml`. * Put CUE schema and composition internals in a clearly internal subpath, for example `.ward/profiles/cue/` or `.ward/profiles/_cue/`. * Put generated output in an explicit render directory only after Ward has a concrete typed input contract, for example `.ward/profiles/rendered/`. Mark it generated and add a drift check. * Add a ward verb in AOS such as `ward exec ward-profile-validate` or `ward exec profile-assets` that runs `cue vet` and, when needed, `cue export`. CUE's own docs support this split: `cue vet` validates data and `cue export` produces concrete JSON/YAML for tools. * Update `docs/ward-profile-assets.md` to define the three layers: YAML is operator source, CUE is validation/composition machinery, rendered files are generated provider inputs. * Do not wire Ward to evaluate `.cue` files at launch. Ward should consume typed data or pinned release artifacts, not import AOS source state live. **Options considered** * Preferred: YAML source plus CUE validation/composition in AOS, with rendered typed artifacts once Ward defines the serialized provider input. This matches the issue decision and keeps CUE behind the curtain. * Minimal first slice: add only schema, sample YAML, docs, and validation. Defer rendered artifacts until Ward exposes the exact file shape. This is safe if the typed provider serialization is not ready. * Ward-integrated CUE provider: not recommended for this issue. It would move CUE into Ward runtime and blur the AOS/Ward ownership line. * CUE as the hand-authored source language: reject. It violates the operator-facing YAML decision. * New `ward-profile` repo: reject. It is explicitly denied by the issue and parent roadmap. **Open questions** * What is Ward's concrete serialized typed provider input? The current seam is typed internally, but the implementation still adapts KDL-backed sources. AOS should not guess whether the durable render is one aggregate file or one file per provider method. * Should profile artifacts ship inside the existing `ward-specs` release tarball, or as a separate `ward-profiles-<tag>.tar.gz` asset? The current tarball logic will miss nested `.ward/profiles/` files unless it is deliberately changed. * Should rendered files be committed, generated only in CI, or attached only as release artifacts? My bias is to commit generated renders only when Ward consumes them from source or tests need drift visibility. Otherwise attach a deterministic release asset. * Where should the CUE toolchain be pinned? Options are dev-base, a Go helper, or CI-local `go run cuelang.org/go/cmd/cue@<version>`. If this becomes pre-commit or CI, dev-base should carry the binary. * What overlay precedence should CUE enforce across profile families? This should be documented before multiple families exist. **Risks** * CUE could accidentally become a second operator language. Avoid this with docs, path naming, and examples that only ask operators to edit YAML. * AOS could become a downward runtime dependency if Ward fetches `.cue` or YAML directly from an AOS checkout. Avoid this by using pinned release artifacts or build-time renders. * Generated artifact drift can make Ward consume stale profile data. Add a drift check once renders exist. * The CUE schema can drift from Ward's private Go types because Ward's current provider returns unexported command-package types. The render contract needs to be explicit before AOS locks a schema. * The existing release packaging does not include nested profile paths. Without a packaging update, the assets can pass locally but never reach Ward's pinned release inputs. * A hard pre-commit dependency on `cue` will fail in current containers until the binary is installed or the hook runs through a pinned helper. **Advisory close** The next engineering pass should stay in `coilyco-flight-deck/agentic-os`: create the `.ward/profiles/` source layout, add CUE schema/validation scaffolding, add a ward-wrapped validation command, and update the profile-assets doc. It should not change Ward runtime behavior yet unless Ward already has a concrete typed file contract ready. If that contract is still absent, the AOS issue can still land as the validated source and documentation base, with the render target left as a named dependency on the Ward typed provider input. --- Researched and posted automatically by `ward agent advisor --harness codex` (ward#179). This is one-shot research, not a carried change - verify before acting on it. <!-- ward-agent-reply --> <!-- ward-agent-signature --> — Codex, via `ward agent`
Author
Member

WARDED_WORKFLOW: #525

details

workflow: pull-request-and-merge; review summary: review gate skipped by ~/.ward/config.yaml default

felt: doc-led and narrow, with the CUE seam landing as a contract update instead of code churn
confidence: high
surprise: the merge gate waits for this authorization comment before it will proceed
follow-ups: none

WARDED_WORKFLOW: https://forgejo.coilysiren.me/coilyco-flight-deck/agentic-os/pulls/525 <details><summary>details</summary> workflow: pull-request-and-merge; review summary: review gate skipped by ~/.ward/config.yaml default felt: doc-led and narrow, with the CUE seam landing as a contract update instead of code churn confidence: high surprise: the merge gate waits for this authorization comment before it will proceed follow-ups: none </details> <!-- ward-agent-signature -->
Author
Member
{
  "verdict": "pass",
  "summary": "Docs-only change that defines the CUE-backed Ward profile pipeline behind the typed seam. The repo gate is green and the PR remains mergeable.",
  "evidence": [
    "Updated docs/ward-profile-assets.md to describe CUE as the validation/composition layer and YAML as the operator-facing source.",
    "Added docs/ward-profile-cue.md to spell out the source roles, flow, and guardrails.",
    "Updated docs/FEATURES.md to keep the shipped feature inventory aligned.",
    "ward exec pre-commit-all passed.",
    "PR #525 checks are green on head SHA 548ac21b37ac359722388e1b34c2fe0e19a63a4a."
  ],
  "risks": [
    "The actual CUE toolchain and concrete `.ward/profiles/` source tree are still a follow-up, not implemented in this repo."
  ],
  "next_steps": [
    "Add the `.ward/profiles/` source layout and validation command when the Ward-side typed profile contract is concrete."
  ]
}
```json { "verdict": "pass", "summary": "Docs-only change that defines the CUE-backed Ward profile pipeline behind the typed seam. The repo gate is green and the PR remains mergeable.", "evidence": [ "Updated docs/ward-profile-assets.md to describe CUE as the validation/composition layer and YAML as the operator-facing source.", "Added docs/ward-profile-cue.md to spell out the source roles, flow, and guardrails.", "Updated docs/FEATURES.md to keep the shipped feature inventory aligned.", "ward exec pre-commit-all passed.", "PR #525 checks are green on head SHA 548ac21b37ac359722388e1b34c2fe0e19a63a4a." ], "risks": [ "The actual CUE toolchain and concrete `.ward/profiles/` source tree are still a follow-up, not implemented in this repo." ], "next_steps": [ "Add the `.ward/profiles/` source layout and validation command when the Ward-side typed profile contract is concrete." ] } ```
Author
Member
{
  "verdict": "pass",
  "summary": "Docs-only change that defines the CUE-backed Ward profile pipeline behind the typed seam. The repo gate is green and the PR remains mergeable.",
  "evidence": [
    "Updated docs/ward-profile-assets.md to describe CUE as the validation/composition layer and YAML as the operator-facing source.",
    "Added docs/ward-profile-cue.md to spell out the source roles, flow, and guardrails.",
    "Updated docs/FEATURES.md to keep the shipped feature inventory aligned.",
    "ward exec pre-commit-all passed.",
    "PR #525 checks are green on head SHA 548ac21b37ac359722388e1b34c2fe0e19a63a4a."
  ],
  "risks": [
    "The actual CUE toolchain and concrete `.ward/profiles/` source tree are still a follow-up, not implemented in this repo."
  ],
  "next_steps": [
    "Add the `.ward/profiles/` source layout and validation command when the Ward-side typed profile contract is concrete."
  ]
}
```json { "verdict": "pass", "summary": "Docs-only change that defines the CUE-backed Ward profile pipeline behind the typed seam. The repo gate is green and the PR remains mergeable.", "evidence": [ "Updated docs/ward-profile-assets.md to describe CUE as the validation/composition layer and YAML as the operator-facing source.", "Added docs/ward-profile-cue.md to spell out the source roles, flow, and guardrails.", "Updated docs/FEATURES.md to keep the shipped feature inventory aligned.", "ward exec pre-commit-all passed.", "PR #525 checks are green on head SHA 548ac21b37ac359722388e1b34c2fe0e19a63a4a." ], "risks": [ "The actual CUE toolchain and concrete `.ward/profiles/` source tree are still a follow-up, not implemented in this repo." ], "next_steps": [ "Add the `.ward/profiles/` source layout and validation command when the Ward-side typed profile contract is concrete." ] } ``` <!-- ward-agent-reply --> <!-- ward-agent-signature -->
Author
Member

WARDED_WORKFLOW: pass

details

workflow: pull-request-and-merge; review summary: review gate skipped by ~/.ward/config.yaml default

{
  "verdict": "pass",
  "summary": "Docs-only change that defines the CUE-backed Ward profile pipeline behind the typed seam. The repo gate is green and the PR remains mergeable.",
  "evidence": [
    "Updated docs/ward-profile-assets.md to describe CUE as the validation/composition layer and YAML as the operator-facing source.",
    "Added docs/ward-profile-cue.md to spell out the source roles, flow, and guardrails.",
    "Updated docs/FEATURES.md to keep the shipped feature inventory aligned.",
    "ward exec pre-commit-all passed.",
    "PR #525 checks are green on head SHA 548ac21b37ac359722388e1b34c2fe0e19a63a4a."
  ],
  "risks": [
    "The actual CUE toolchain and concrete `.ward/profiles/` source tree are still a follow-up, not implemented in this repo."
  ],
  "next_steps": [
    "Add the `.ward/profiles/` source layout and validation command when the Ward-side typed profile contract is concrete."
  ]
}

felt: doc-led and narrow, with the CUE seam landing as a contract update instead of code churn
confidence: high
surprise: the merge gate wanted a status-line QA verdict, not just the JSON block
follow-ups: none

WARDED_WORKFLOW: pass <details><summary>details</summary> workflow: pull-request-and-merge; review summary: review gate skipped by ~/.ward/config.yaml default ```json { "verdict": "pass", "summary": "Docs-only change that defines the CUE-backed Ward profile pipeline behind the typed seam. The repo gate is green and the PR remains mergeable.", "evidence": [ "Updated docs/ward-profile-assets.md to describe CUE as the validation/composition layer and YAML as the operator-facing source.", "Added docs/ward-profile-cue.md to spell out the source roles, flow, and guardrails.", "Updated docs/FEATURES.md to keep the shipped feature inventory aligned.", "ward exec pre-commit-all passed.", "PR #525 checks are green on head SHA 548ac21b37ac359722388e1b34c2fe0e19a63a4a." ], "risks": [ "The actual CUE toolchain and concrete `.ward/profiles/` source tree are still a follow-up, not implemented in this repo." ], "next_steps": [ "Add the `.ward/profiles/` source layout and validation command when the Ward-side typed profile contract is concrete." ] } ``` felt: doc-led and narrow, with the CUE seam landing as a contract update instead of code churn confidence: high surprise: the merge gate wanted a status-line QA verdict, not just the JSON block follow-ups: none </details> <!-- ward-agent-signature -->
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
coilyco-flight-deck/agentic-os#523
No description provided.