From 7b99c038a3f88f51b4001758b3aca385386e8d9f Mon Sep 17 00:00:00 2001 From: Christopher Maher Date: Fri, 10 Jul 2026 00:16:26 -0700 Subject: [PATCH] feat(foreman): ship default integrate/reconcile Agents for sliced workloads The Sliced Workloads pipeline (#1033) dispatches an integrate step (run_integrate) and a reconcile step (run_reconcile), but no Agent CRs backed them, so a rendered sliced Workload failed at those steps with 'agent not found'. Add the two deterministic Agents under config/foreman/agents/ mirroring gate.yaml (no inferenceServiceRef, tool-only). Unlike the gate (which runs a remote Job on a verifier node), integrate/reconcile do LOCAL git in the agent workspace, so they requiredCapability roles: [coder] to schedule onto a node whose foreman-agent has --git-remote-url configured. Fixes #1051 Signed-off-by: Christopher Maher --- config/foreman/agents/integrate.yaml | 38 ++++++++++++++++++++++++++++ config/foreman/agents/reconcile.yaml | 38 ++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 config/foreman/agents/integrate.yaml create mode 100644 config/foreman/agents/reconcile.yaml diff --git a/config/foreman/agents/integrate.yaml b/config/foreman/agents/integrate.yaml new file mode 100644 index 00000000..cbbef160 --- /dev/null +++ b/config/foreman/agents/integrate.yaml @@ -0,0 +1,38 @@ +# Foreman integrate Agent: the integrate step of a Sliced Workload (#1033). +# Deterministic (no inferenceServiceRef, no LLM in the loop); the executor's +# executeDeterministic() branch dispatches its single tool, run_integrate, +# with the task payload as JSON arguments. run_integrate unions the disjoint +# slice branches onto the current base and pushes the integration branch. +# +# Apply into the namespace where sliced Workloads run: +# +# kubectl apply -f config/foreman/agents/integrate.yaml +# +# Like config/foreman/agents/gate.yaml, this ships with the foreman chart but +# is NOT a chart template; the chart installs the controller, the Agent CR is +# workload-data. Apply once per cluster + namespace. +apiVersion: foreman.llmkube.dev/v1alpha1 +kind: Agent +metadata: + name: integrate + namespace: default + labels: + app.kubernetes.io/part-of: foreman + foreman.llmkube.dev/role: verifier +spec: + role: verifier + # Deterministic: inferenceServiceRef and systemPrompt are omitted (there is + # no model to prompt); the empty .name routes through executeDeterministic(). + tools: + - run_integrate + requiredCapability: + # run_integrate does a LOCAL git clone/union in the agent workspace, so it + # must schedule onto a node whose foreman-agent has --git-remote-url set + # (the coder-capable nodes), not the verifier node that runs remote Jobs. + # Adjust to match your fleet's FleetNode roles. + roles: + - coder + # Bounds run_integrate's own retry on transient git/apiserver errors. + maxRetries: 3 + # The union + fetch/push are quick; bound the whole step. + requestTimeoutSeconds: 900 diff --git a/config/foreman/agents/reconcile.yaml b/config/foreman/agents/reconcile.yaml new file mode 100644 index 00000000..033db86a --- /dev/null +++ b/config/foreman/agents/reconcile.yaml @@ -0,0 +1,38 @@ +# Foreman reconcile Agent: the reconcile step of a Sliced Workload (#1033). +# Deterministic (no inferenceServiceRef, no LLM in the loop); the executor's +# executeDeterministic() branch dispatches its single tool, run_reconcile, +# with the task payload as JSON arguments. run_reconcile checks the integrated +# union against the plan's pinned shared identifiers for cross-slice drift. +# +# Apply into the namespace where sliced Workloads run: +# +# kubectl apply -f config/foreman/agents/reconcile.yaml +# +# Like config/foreman/agents/gate.yaml, this ships with the foreman chart but +# is NOT a chart template; the chart installs the controller, the Agent CR is +# workload-data. Apply once per cluster + namespace. +apiVersion: foreman.llmkube.dev/v1alpha1 +kind: Agent +metadata: + name: reconcile + namespace: default + labels: + app.kubernetes.io/part-of: foreman + foreman.llmkube.dev/role: verifier +spec: + role: verifier + # Deterministic: inferenceServiceRef and systemPrompt are omitted (there is + # no model to prompt); the empty .name routes through executeDeterministic(). + tools: + - run_reconcile + requiredCapability: + # run_reconcile does a LOCAL git checkout + file read in the agent workspace, so it + # must schedule onto a node whose foreman-agent has --git-remote-url set + # (the coder-capable nodes), not the verifier node that runs remote Jobs. + # Adjust to match your fleet's FleetNode roles. + roles: + - coder + # Bounds run_reconcile's own retry on transient git/apiserver errors. + maxRetries: 3 + # The fetch + pinned check are quick; bound the whole step. + requestTimeoutSeconds: 900