Skip to content

✨ Optional Agent gateways, default content, and operator manifest sync - #215

Merged
djzager merged 6 commits into
konveyor:mainfrom
djzager:operator-manifest-sync
Sep 4, 2026
Merged

✨ Optional Agent gateways, default content, and operator manifest sync#215
djzager merged 6 commits into
konveyor:mainfrom
djzager:operator-manifest-sync

Conversation

@djzager

@djzager djzager commented Sep 2, 2026

Copy link
Copy Markdown
Member

Three intertwined workstreams in one PR.

#209Agent.spec.gateways is optional

The gateway list becomes a presence-gated curation constraint:

  • When an Agent declares gateways, an AgentRun's gateway must be one of them (an architect can lock an Agent to specific gateways). A single declared gateway is defaulted for runs that omit one.
  • When the list is empty/omitted, the controller constrains nothing — the AgentRun must name a gateway itself, which must exist and be Ready.
  • An Agent with no gateways is a valid, Ready template, so curated Agents can ship without binding to a customer's Gateway.
  • Adds a GatewayConfigured status condition (NoGatewaysDeclared / GatewaysNotReady / GatewaysReady), separate from Ready, so the UI can surface not-runnable state the Kubernetes-native way without treating the Agent as unhealthy.

#210 — Ship default content

  • New config/defaults/ holds the curated content the operator installs on enable: the plan/execute/verify SkillCards, the java-migration SkillCollection, the stage Agents (no gateway), and the java-ee-to-quarkus AgentWorkflow.
  • config/samples/ now holds only illustrative CRs you copy and edit (per-provider Gateways + a standalone example Agent/AgentRun).
  • The gcp-vertex-ai placeholder is dropped from the shipped Agents.
  • CONTEXT.md gains a Packaging glossary (Default vs. Sample); README and getting-started updated.

#190 — Push-sync to the operator

  • hack/sync-operator.sh renders CRDs (verbatim), RBAC (textual rename + label-strip, byte-identical to the operator's committed role files), and config/defaults/ into a konveyor/operator checkout.
  • .github/workflows/sync-operator.yml runs on merge to main/release-*: syncs, runs make bundle to regenerate the CSV, filters CSV createdAt churn, and force-pushes a fixed branch to open (or update) one PR on konveyor/operator via the Konveyor CI app.

Testing

make test (79% controller coverage), make lint (0 issues), and changelog validation all pass. The full sync pipeline was verified end-to-end against a real konveyor/operator clone (first-sync detection, no-op idempotency, deterministic RBAC render).

Manual follow-ups on konveyor/operator (one-time)

  • Wire an Ansible task in roles/tackle/tasks/agentic.yml to k8s apply the synced roles/tackle/templates/agentic/defaults/*.yaml into the enabled namespace (the sync lands the files; applying them is the operator's job).
  • Confirm the Konveyor CI app has contents:write + pull_requests:write on konveyor/operator.

Closes #209
Closes #210
Closes #190

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: 5a80ae38-c830-4fdc-99d8-e0ce340d794d


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@djzager
djzager force-pushed the operator-manifest-sync branch 4 times, most recently from 25e90cf to ff333fb Compare September 2, 2026 20:21

@ibolton336 ibolton336 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Read through all three workstreams — the design hangs together well (optional gateways is exactly what lets the shipped default Agents be gateway-free and therefore safe to sync into the operator). validateGateway covers all the branches correctly, every other Spec.Gateways use is empty-safe, and the deployment_parity_test anti-drift guard is a nice touch. Two minor things, neither blocking:

  1. Mistyped gateway on a no-gateways Agent never terminates. With a non-empty list, a bad spec.gateway fails fast → terminal Failed (InvalidGateway). With an empty list, validateGateway accepts any name, so a nonexistent gateway flows into createSandbox, hits NotFound, and is treated as transientSucceeded=Unknown "SandboxCreationFailed", requeuing indefinitely rather than reaching Failed. Message is clear and it's arguably consistent with existing transient-createSandbox handling (a gateway could be created later), so this may be intended — just flagging the asymmetry against the "fail fast" rationale in the comments. Deliberate?

  2. sync-operator.sh clears the defaults dir but not the CRD dir. defaults_dir is rm -f'd before copy so a removed default disappears downstream, but the CRD copy is a plain cp konveyor.io_*.yaml — a renamed/removed CRD would leave a stale file in the operator. Low likelihood, just inconsistent with the defaults handling.

One note on the operator-side follow-up: until the Ansible k8s apply task lands, the sync copies the default-content files but nothing applies them, so the "populated UI day one" goal isn't live yet. Worth making sure that task doesn't get lost.

@savitharaghunathan savitharaghunathan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work pulling these three workstreams together — the docstrings and comments make the intent really easy to follow. Here's what stood out, starting with the ones I'd want eyes on first:

Gateway validation gap for zero-gateway Agents

In validateGateway (agentrun_controller.go:413), when the Agent has no declared gateways, we accept whatever run.Spec.Gateway the user typed without checking it exists. That's fine as a design ("createSandbox will catch it"), but the failure mode is different from what we do elsewhere: a typo'd gateway name surfaces later in buildEnvVars as SandboxCreationFailed with ConditionUnknown, which gets retried forever with backoff — instead of failing fast with a terminal condition like the membership-violation case does. Might be worth treating "gateway doesn't exist" as terminal here too, since a typo isn't going to fix itself on retry.

Workflow gateway errors point users at the wrong resource

The default java-ee-to-quarkus stage Agents ship with no gateways, so if someone creates an AgentWorkflowRun without spec.gateway, the error ends up on the workflow-owned child AgentRun ("agent %q declares no gateways; select one via spec.gateway") — but that AgentRun is immutable and controller-managed, so there's nothing the user can actually do to it. On top of that, the parent AgentWorkflowRun only surfaces the child's Reason (InvalidGateway), not the actual message, so the guidance never reaches the resource the user can edit. Also worth noting: docs/getting-started.md's Workflows section and hack/harness-test/workflow-resources.yaml both use gateway-bearing Agents, so this path isn't exercised anywhere. Could we either propagate the message up to the AgentWorkflowRun, or have the error explicitly say "set spec.gateway on the AgentWorkflowRun"?

A couple of stale config/samples/ references from the defaults split

Now that SkillCards/SkillCollections moved to config/defaults/, these two spots still point at config/samples/:

  • hack/setup-e2e.sh:138-146 applies config/samples/ then asserts kubectl get skillcards/skillcollections — this will just print "No resources found" now.
  • config/default/kustomization.yaml:21's comment still says "Apply with: kubectl apply -k config/samples/ -n <namespace>" for default skill resources.

Missing printcolumn for the new condition

GatewayConfigured (api/v1alpha1/agent_types.go) doesn't have a +kubebuilder:printcolumn, so kubectl get agents won't show it even though the whole point per the comment is to surface not-runnable state "the Kubernetes-native way." SkillCard's Resolvable condition has one — could we add the same here?

Two smaller ones on the operator sync workflow

  • hack/sync-operator.sh:64 renames the RBAC role via an exact-string/indentation-sniffing awk script. Since yq is already a build dependency, might be more robust to use that — if controller-gen ever reformats the RBAC YAML, this awk silently no-ops and we'd ship a name collision into the operator's helm chart without any error.
  • .github/workflows/sync-operator.yml:76 checks out konveyor/operator at the exact same branch name as the trigger, with no fallback. If we ever cut a new release-* branch here before the matching branch exists upstream, every sync run on that branch fails until someone manually creates it there.

Nothing here feels blocking except maybe the first two — happy to pair on either if useful!

djzager added a commit to djzager/agentic-controller that referenced this pull request Sep 3, 2026
Address PR konveyor#215 review feedback:

- validateGateway accepts any name when an Agent declares no gateways
  (an empty list constrains nothing), so a nonexistent gateway used to
  reach createSandbox and be treated as transient (SandboxCreationFailed,
  Succeeded=Unknown), requeuing indefinitely. A Gateway NotFound is now
  wrapped in an errGatewayNotFound sentinel and mapped to a terminal
  Failed/InvalidGateway in Reconcile, matching the constrained path's
  fail-fast behavior. A gateway that exists but is not Ready, and missing
  SkillCards/SkillCollections, stay transient as before.

- hack/sync-operator.sh copied CRDs without clearing the destination
  first, unlike the defaults sync, so a renamed or removed CRD left a
  stale file downstream. Clear konveyor.io_*.yaml (our prefix only, so
  other operators' CRDs are untouched) before copying.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: David Zager <david.j.zager@gmail.com>
djzager added a commit to djzager/agentic-controller that referenced this pull request Sep 3, 2026
…lumn, stale refs

Remaining feedback from savitharaghunathan's review (the gateway fail-fast
item was already handled in 26584eb):

- agentworkflowrun_controller: surface a failed stage's full message on the
  AgentWorkflowRun, not just its Reason. The child AgentRun is immutable and
  controller-managed, so its status is a dead end; guidance like "select one
  via spec.gateway" now reaches the editable AgentWorkflowRun (whose own
  spec.gateway feeds the stage, so the message reads correctly there). Extends
  the "stage fails" test to assert propagation.

- agent_types: add a GatewayConfigured +kubebuilder:printcolumn so
  `kubectl get agents` shows not-runnable state, matching SkillCard's
  Resolvable column. Regenerated the CRD.

- Fix two stale config/samples/ references left by the defaults split:
  hack/setup-e2e.sh now applies config/defaults/ (where SkillCards live) so
  its skillcards/skillcollections assertions pass; config/default's comment
  points at config/defaults/.

- hack/sync-operator.sh: guard the exact-match RBAC rename -- fail loudly if
  controller-gen reformatting makes it silently no-op (which would ship a role
  name collision). Keeps the deliberate byte-for-byte textual transform rather
  than reserializing with yq.

- sync-operator.yml: when konveyor/operator has no matching release-* branch
  yet, skip cleanly with a warning instead of failing every run. Does not fall
  back to main (that branch is driven by this repo's own main sync).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
djzager added a commit to djzager/agentic-controller that referenced this pull request Sep 3, 2026
…lumn, stale refs

Remaining feedback from savitharaghunathan's review (the gateway fail-fast
item was already handled in 26584eb):

- agentworkflowrun_controller: surface a failed stage's full message on the
  AgentWorkflowRun, not just its Reason. The child AgentRun is immutable and
  controller-managed, so its status is a dead end; guidance like "select one
  via spec.gateway" now reaches the editable AgentWorkflowRun (whose own
  spec.gateway feeds the stage, so the message reads correctly there). Extends
  the "stage fails" test to assert propagation.

- agent_types: add a GatewayConfigured +kubebuilder:printcolumn so
  `kubectl get agents` shows not-runnable state, matching SkillCard's
  Resolvable column. Regenerated the CRD.

- Fix two stale config/samples/ references left by the defaults split:
  hack/setup-e2e.sh now applies config/defaults/ (where SkillCards live) so
  its skillcards/skillcollections assertions pass; config/default's comment
  points at config/defaults/.

- hack/sync-operator.sh: guard the exact-match RBAC rename -- fail loudly if
  controller-gen reformatting makes it silently no-op (which would ship a role
  name collision). Keeps the deliberate byte-for-byte textual transform rather
  than reserializing with yq.

- sync-operator.yml: when konveyor/operator has no matching release-* branch
  yet, skip cleanly with a warning instead of failing every run. Does not fall
  back to main (that branch is driven by this repo's own main sync).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: David Zager <david.j.zager@gmail.com>
@djzager
djzager force-pushed the operator-manifest-sync branch from ba72044 to a29c605 Compare September 3, 2026 16:59

@ibolton336 ibolton336 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One blocking workflow-reliability finding is inline; I did not find a controller state-machine regression. Non-blocking documentation mismatch: AgentRunSpec.Gateway (and therefore its CRD description) still says the gateway must be declared on the Agent, but this PR allows any Ready Gateway when the Agent list is empty.

Validated the exact head with clean generation/gofmt drift checks, go vet ./..., and the full non-e2e go test suite. actionlint, both kustomize renders, and a two-pass operator-sync smoke/idempotence test also passed. DCO is green; the remaining CI jobs were still in progress when reviewed.

Comment thread .github/workflows/sync-operator.yml Outdated
GH_TOKEN: ${{ steps.token.outputs.token }}
BASE: ${{ steps.branches.outputs.base }}
run: |
if gh api "repos/konveyor/operator/branches/${BASE}" >/dev/null 2>&1; then

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking: This treats every gh api failure as “branch absent” and lets the job succeed. GitHub also returns 404 when the App cannot access konveyor/operator, so the bot installation/permission issue called out in the PR description would be silently masked and no sync PR would appear; 5xx/network failures are swallowed too. Please skip only a confirmed missing-branch response and fail on repository-access/auth or other API errors.

djzager added a commit to djzager/agentic-controller that referenced this pull request Sep 3, 2026
…ateway doc

- The operator-sync workflow's branch-existence check treated every gh api
  failure as "branch absent", so a 404 from the bot App lacking access to
  konveyor/operator (or a 5xx/network error) silently skipped the sync with
  a green job. Query the actual HTTP status: confirm repo access first
  (non-200 -> fail with an auth/access error), then skip only on a genuine
  404 for the branch and fail on any other status.

- AgentRunSpec.Gateway godoc still said the gateway must be one declared on
  the Agent, contradicting this PR's behavior. Clarify: one of the Agent's
  gateways when it declares any, any Ready Gateway when it declares none,
  omittable only when the Agent declares exactly one. Regenerate the CRD.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: David Zager <david.j.zager@gmail.com>

@savitharaghunathan savitharaghunathan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two things I'd love a second look at before this merges — nothing blocking, just flagging for discussion.

@@ -752,6 +790,9 @@ func (r *AgentRunReconciler) buildEnvVars(
var gateway konveyoriov1alpha1.Gateway
gwKey := types.NamespacedName{Namespace: run.Namespace, Name: run.Spec.Gateway}
if err := r.Get(ctx, gwKey, &gateway); err != nil {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch extending the fail-fast pattern to Gateway lookups for the unconstrained-Agent case — makes sense to match how validateGateway already handles a bad name on a constrained one.

One thing worth double-checking though: r.Get here reads through the manager's cache, and Gateway isn't excluded from it in cmd/main.go. If a Gateway, Agent, and AgentRun are applied together (e.g. one bundle/GitOps sync), there's a window where the informer hasn't synced the new Gateway yet, IsNotFound fires, and the AgentRun gets marked Failed/InvalidGateway permanently — since the spec is immutable, that means delete-and-recreate to recover from what was really just a timing issue, not a bad reference.

To be clear, this isn't new to this PR — the Agent lookup a few lines up (AgentNotFound) has had the exact same cache-vs-terminal-failure shape since #4, so this change is just staying consistent with existing behavior rather than introducing something novel. Might be worth a follow-up (maybe a short requeue-and-retry before declaring terminal, for both Agent and Gateway) rather than blocking this PR on it — curious what you think given you've clearly already thought about cache lag elsewhere in this file (the apiReader for pod termination messages).

Comment thread config/samples/kustomization.yaml Outdated
#
# plan and javaee-to-quarkus come out of one image, each selected with
# subPath; house-rules is inline and needs no image at all.
# kubectl apply -k config/samples/

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small inconsistency here: the comment block says to "pick the one for your provider" and docs/getting-started.md applies exactly one gateway sample at a time with kubectl apply -f, but the kustomization aggregates all 5 provider Gateways as resources, and the header instructs kubectl apply -k config/samples/. If someone follows the header literally instead of getting-started.md, they'll end up creating all 5 Gateways at once, most referencing Secrets they never made.

Might just need the header comment/resources list trimmed down to match the "pick one" intent — happy to be wrong if there's a reason to keep all 5 wired up here.

djzager added a commit that referenced this pull request Sep 4, 2026
## What

Bumps `sigs.k8s.io/agent-sandbox` from **v0.5.0 → v1.0.0**. Independent
of #215 — branched off `main`.

## Why / what changed

- **go.mod / go.sum** — pin `agent-sandbox v1.0.0`. The transitive
`k8s.io/* → v0.36.4` bump (and the otel/grpc/etc. moves) is required by
agent-sandbox v1.0.0's own go.mod; the rest fall out of `go mod tidy`.
- **Controller** — v1.0.0 restructured `SandboxSpec` (`PodTemplate` and
`Service` moved into an embedded `SandboxBlueprint`), so `createSandbox`
now builds the CR through the new shape. The controller still consumes
only the `v1beta1` API and the **serialized Sandbox is unchanged**.
- **e2e install tag** — `hack/start-kind.sh` now derives
`AGENT_SANDBOX_TAG` from go.mod (via `go -C … list -m`) so the deployed
CRDs can't drift from the compiled API, mirroring the go.mod-derived CRD
path in `suite_test.go`. Env override preserved.
- **Docs** — README + getting-started target v1.0.x, with an
in-place-upgrade note (v1.0.0 removes the legacy `v1alpha1` API and
conversion webhooks; existing clusters must migrate via v0.5.2+ before
upgrading).

## Testing

- `go build ./...` ✅
- `make test` ✅ — controller specs pass; `manifests`/`generate` produced
**no CRD/RBAC drift** (the `agents.x-k8s.io` group is unchanged),
confirming the API is compatible.

> Note: not exercised end-to-end against a live v1.0.0 Sandbox
controller (`make test` uses envtest). An `e2e-setup` run against the
new tag is the final confidence check.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: David Zager <david.j.zager@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
djzager added a commit to djzager/agentic-controller that referenced this pull request Sep 4, 2026
Address savitharaghunathan's review:

- A named Gateway that does not exist is no longer terminal. Marking a run
  Failed/InvalidGateway stranded it when the miss was just a timing issue
  (Gateway+Agent+AgentRun applied together, informer cache not yet synced),
  since the AgentRun spec is immutable. Treat it like a missing container
  image (ImagePullBackOff): surface a distinct GatewayNotFound reason with
  Succeeded=Unknown and requeue with backoff, so the run recovers on its own
  once the Gateway appears. Agent-not-found stays terminal: a missing
  referenced Agent is far more often a real typo than a timing artifact.

- config/samples/kustomization.yaml aggregated all five provider Gateways
  under an "apply -k" header, so following it literally created every
  provider's Gateway at once (most referencing Secrets the user never made),
  contradicting the "pick one, apply -f" model in getting-started. Stop
  aggregating them and direct users to apply the single gateway they need.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
djzager added a commit to djzager/agentic-controller that referenced this pull request Sep 4, 2026
Address PR konveyor#215 review feedback:

- validateGateway accepts any name when an Agent declares no gateways
  (an empty list constrains nothing), so a nonexistent gateway used to
  reach createSandbox and be treated as transient (SandboxCreationFailed,
  Succeeded=Unknown), requeuing indefinitely. A Gateway NotFound is now
  wrapped in an errGatewayNotFound sentinel and mapped to a terminal
  Failed/InvalidGateway in Reconcile, matching the constrained path's
  fail-fast behavior. A gateway that exists but is not Ready, and missing
  SkillCards/SkillCollections, stay transient as before.

- hack/sync-operator.sh copied CRDs without clearing the destination
  first, unlike the defaults sync, so a renamed or removed CRD left a
  stale file downstream. Clear konveyor.io_*.yaml (our prefix only, so
  other operators' CRDs are untouched) before copying.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: David Zager <david.j.zager@gmail.com>
djzager added a commit to djzager/agentic-controller that referenced this pull request Sep 4, 2026
…lumn, stale refs

Remaining feedback from savitharaghunathan's review (the gateway fail-fast
item was already handled in 26584eb):

- agentworkflowrun_controller: surface a failed stage's full message on the
  AgentWorkflowRun, not just its Reason. The child AgentRun is immutable and
  controller-managed, so its status is a dead end; guidance like "select one
  via spec.gateway" now reaches the editable AgentWorkflowRun (whose own
  spec.gateway feeds the stage, so the message reads correctly there). Extends
  the "stage fails" test to assert propagation.

- agent_types: add a GatewayConfigured +kubebuilder:printcolumn so
  `kubectl get agents` shows not-runnable state, matching SkillCard's
  Resolvable column. Regenerated the CRD.

- Fix two stale config/samples/ references left by the defaults split:
  hack/setup-e2e.sh now applies config/defaults/ (where SkillCards live) so
  its skillcards/skillcollections assertions pass; config/default's comment
  points at config/defaults/.

- hack/sync-operator.sh: guard the exact-match RBAC rename -- fail loudly if
  controller-gen reformatting makes it silently no-op (which would ship a role
  name collision). Keeps the deliberate byte-for-byte textual transform rather
  than reserializing with yq.

- sync-operator.yml: when konveyor/operator has no matching release-* branch
  yet, skip cleanly with a warning instead of failing every run. Does not fall
  back to main (that branch is driven by this repo's own main sync).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: David Zager <david.j.zager@gmail.com>
djzager added a commit to djzager/agentic-controller that referenced this pull request Sep 4, 2026
…ateway doc

- The operator-sync workflow's branch-existence check treated every gh api
  failure as "branch absent", so a 404 from the bot App lacking access to
  konveyor/operator (or a 5xx/network error) silently skipped the sync with
  a green job. Query the actual HTTP status: confirm repo access first
  (non-200 -> fail with an auth/access error), then skip only on a genuine
  404 for the branch and fail on any other status.

- AgentRunSpec.Gateway godoc still said the gateway must be one declared on
  the Agent, contradicting this PR's behavior. Clarify: one of the Agent's
  gateways when it declares any, any Ready Gateway when it declares none,
  omittable only when the Agent declares exactly one. Regenerate the CRD.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: David Zager <david.j.zager@gmail.com>
djzager added a commit to djzager/agentic-controller that referenced this pull request Sep 4, 2026
Address savitharaghunathan's review:

- A named Gateway that does not exist is no longer terminal. Marking a run
  Failed/InvalidGateway stranded it when the miss was just a timing issue
  (Gateway+Agent+AgentRun applied together, informer cache not yet synced),
  since the AgentRun spec is immutable. Treat it like a missing container
  image (ImagePullBackOff): surface a distinct GatewayNotFound reason with
  Succeeded=Unknown and requeue with backoff, so the run recovers on its own
  once the Gateway appears. Agent-not-found stays terminal: a missing
  referenced Agent is far more often a real typo than a timing artifact.

- config/samples/kustomization.yaml aggregated all five provider Gateways
  under an "apply -k" header, so following it literally created every
  provider's Gateway at once (most referencing Secrets the user never made),
  contradicting the "pick one, apply -f" model in getting-started. Stop
  aggregating them and direct users to apply the single gateway they need.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: David Zager <david.j.zager@gmail.com>
@djzager
djzager force-pushed the operator-manifest-sync branch from f35fc70 to c982a1e Compare September 4, 2026 15:54
djzager and others added 3 commits September 4, 2026 12:44
Three intertwined workstreams:

- konveyor#209: Make Agent.spec.gateways optional as a presence-gated curation
  constraint. When an Agent declares gateways an AgentRun must select one;
  when it declares none the Agent is still a valid, Ready template and the
  run names its own gateway. Adds a GatewayConfigured status condition so the
  UI can surface not-runnable state without treating the Agent as unhealthy.

- konveyor#210: Move curated content to config/defaults/ (skill catalog, stage
  Agents with no gateway, java-ee-to-quarkus AgentWorkflow); config/samples/
  keeps only illustrative Gateways and an example Agent/AgentRun.

- konveyor#190: Add .github/workflows/sync-operator.yml + hack/sync-operator.sh to
  render CRDs, RBAC, and config/defaults into konveyor/operator, regenerate
  the OLM bundle, and force-push a fixed branch opening/updating one PR.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: David Zager <david.j.zager@gmail.com>
Address PR konveyor#215 review feedback:

- validateGateway accepts any name when an Agent declares no gateways
  (an empty list constrains nothing), so a nonexistent gateway used to
  reach createSandbox and be treated as transient (SandboxCreationFailed,
  Succeeded=Unknown), requeuing indefinitely. A Gateway NotFound is now
  wrapped in an errGatewayNotFound sentinel and mapped to a terminal
  Failed/InvalidGateway in Reconcile, matching the constrained path's
  fail-fast behavior. A gateway that exists but is not Ready, and missing
  SkillCards/SkillCollections, stay transient as before.

- hack/sync-operator.sh copied CRDs without clearing the destination
  first, unlike the defaults sync, so a renamed or removed CRD left a
  stale file downstream. Clear konveyor.io_*.yaml (our prefix only, so
  other operators' CRDs are untouched) before copying.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: David Zager <david.j.zager@gmail.com>
…lumn, stale refs

Remaining feedback from savitharaghunathan's review (the gateway fail-fast
item was already handled in 26584eb):

- agentworkflowrun_controller: surface a failed stage's full message on the
  AgentWorkflowRun, not just its Reason. The child AgentRun is immutable and
  controller-managed, so its status is a dead end; guidance like "select one
  via spec.gateway" now reaches the editable AgentWorkflowRun (whose own
  spec.gateway feeds the stage, so the message reads correctly there). Extends
  the "stage fails" test to assert propagation.

- agent_types: add a GatewayConfigured +kubebuilder:printcolumn so
  `kubectl get agents` shows not-runnable state, matching SkillCard's
  Resolvable column. Regenerated the CRD.

- Fix two stale config/samples/ references left by the defaults split:
  hack/setup-e2e.sh now applies config/defaults/ (where SkillCards live) so
  its skillcards/skillcollections assertions pass; config/default's comment
  points at config/defaults/.

- hack/sync-operator.sh: guard the exact-match RBAC rename -- fail loudly if
  controller-gen reformatting makes it silently no-op (which would ship a role
  name collision). Keeps the deliberate byte-for-byte textual transform rather
  than reserializing with yq.

- sync-operator.yml: when konveyor/operator has no matching release-* branch
  yet, skip cleanly with a warning instead of failing every run. Does not fall
  back to main (that branch is driven by this repo's own main sync).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: David Zager <david.j.zager@gmail.com>
djzager and others added 3 commits September 4, 2026 12:44
…ateway doc

- The operator-sync workflow's branch-existence check treated every gh api
  failure as "branch absent", so a 404 from the bot App lacking access to
  konveyor/operator (or a 5xx/network error) silently skipped the sync with
  a green job. Query the actual HTTP status: confirm repo access first
  (non-200 -> fail with an auth/access error), then skip only on a genuine
  404 for the branch and fail on any other status.

- AgentRunSpec.Gateway godoc still said the gateway must be one declared on
  the Agent, contradicting this PR's behavior. Clarify: one of the Agent's
  gateways when it declares any, any Ready Gateway when it declares none,
  omittable only when the Agent declares exactly one. Regenerate the CRD.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: David Zager <david.j.zager@gmail.com>
Address savitharaghunathan's review:

- A named Gateway that does not exist is no longer terminal. Marking a run
  Failed/InvalidGateway stranded it when the miss was just a timing issue
  (Gateway+Agent+AgentRun applied together, informer cache not yet synced),
  since the AgentRun spec is immutable. Treat it like a missing container
  image (ImagePullBackOff): surface a distinct GatewayNotFound reason with
  Succeeded=Unknown and requeue with backoff, so the run recovers on its own
  once the Gateway appears. Agent-not-found stays terminal: a missing
  referenced Agent is far more often a real typo than a timing artifact.

- config/samples/kustomization.yaml aggregated all five provider Gateways
  under an "apply -k" header, so following it literally created every
  provider's Gateway at once (most referencing Secrets the user never made),
  contradicting the "pick one, apply -f" model in getting-started. Stop
  aggregating them and direct users to apply the single gateway they need.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: David Zager <david.j.zager@gmail.com>
Add app.kubernetes.io/managed-by: agentic-controller-defaults to every
config/defaults/ CR. The operator installs this curated content and needs a
way to tell it apart from user-created SkillCards/Agents so it can prune
defaults that are later removed from the catalog without touching a user's
own resources. Applying the label at the source lets it flow through the
sync verbatim; the objects carry it once installed, so the prune can select
on it. The prune itself is deferred (see konveyor/operator), but labeling
now avoids having to backfill already-installed content later.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@djzager
djzager force-pushed the operator-manifest-sync branch from c982a1e to 2ad3a48 Compare September 4, 2026 16:45
@djzager
djzager merged commit 280883e into konveyor:main Sep 4, 2026
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants