Skip to content

phase2(s13): config authority via refs — InferencePolicy + ToolPolicy - #118

Merged
Pal Lakatos-Toth (pallakatos) merged 1 commit into
devfrom
phase2-s13-config-authority-refs
Apr 30, 2026
Merged

Pal Lakatos-Toth (pallakatos) merged 1 commit into
devfrom
phase2-s13-config-authority-refs

Conversation

@pallakatos

Copy link
Copy Markdown
Collaborator

S13 phase2-config-authority-refs

BREAKING in-place v1alpha1 schema edit (pre-release; no conversion webhook).
Inline inference and tool-policy config on ClawSandbox is removed; the
spec now carries same-namespace refs to dedicated InferencePolicy and
ToolPolicy CRDs which become the single source of truth.

Schema changes

Before After
spec.inference: InferenceConfig (provider/model/contentSafety/promptShields/tokenBudget) spec.inferenceRef: { name } — required, sibling InferencePolicy CR
spec.governance.toolPolicy: string (profile name) spec.governance.toolPolicyRef: { name } — required when governance.enabled=true
  • Same-namespace constraint: Api::namespaced(client, &sandbox_self_ns).
    Cross-namespace refs are deliberately not supported — a sandbox author
    must not be able to "borrow" policies from another tenant.
  • New status reasons InferencePolicyNotFound, ToolPolicyNotFound
    emitted on Degraded when the referenced CR is missing.
  • Printcolumn updated: Model → InferencePolicy (.spec.inferenceRef.name).

Reconciler

controller/src/reconciler/mod.rs resolves InferencePolicy after
isolation validation and ToolPolicy after the governance block is
parsed. Hoisted vars inference_model, content_safety_enabled,
prompt_shields_enabled, token_budget_{daily,per_request},
tool_policy_profile replace the previous inline reads. The
agt-policy-{profile} ConfigMap convention and the
azureclaw-default.yaml / azureclaw-offload.yaml selection are
preserved — the resolved ToolPolicy's metadata.name doubles as the
profile identifier.

CLI

  • New cli/src/refs.ts: kebabRefName helper (DNS-1123 truncated to 63
    chars) + buildInferencePolicy / buildToolPolicy emitters.
  • azureclaw up and azureclaw add now emit a multi-doc bundle
    (InferencePolicy + optional ToolPolicy + ClawSandbox) applied
    as a single kubectl apply of a v1.List manifest.
  • azureclaw migrate from-kagent always emits an
    <sandbox>-inference InferencePolicy (preserving kagent
    modelConfig as a provenance annotation when set) and a synthetic
    <sandbox>-toolpolicy aggregator whenever governance is on.
  • attest.ts recognizes both inferenceRef (S13) and the pre-S13
    inferencePolicyRef shape during the rollout window.

Test delta

  • Controller: 381 tests passing. Removed default_model_is_gpt_4_1,
    default_provider_is_azure_openai, default_inference_* /
    inference_config_default_has_no_fallback / token_budget_config_*.
    Added local_object_ref_round_trips,
    local_object_ref_default_is_empty_name,
    inference_ref_round_trips_via_camel_case,
    governance_tool_policy_ref_serializes_camel_case. Updated
    default_governance_config and sandbox_spec_fields_all_optional.
    LocalObjectRef is reused from the existing
    crate::mcp_server::LocalObjectRef (same shape, identical semantics).
  • CLI: 395 tests passing. add.test.ts updated to assert
    spec.inferenceRef.name === "<sandbox>-inference" and
    spec.governance.toolPolicyRef. from_kagent.test.ts updated
    for the always-emit-InferencePolicy and <sandbox>-toolpolicy
    aggregator semantics; per-tool ToolPolicy count assertions filter
    out the aggregator.

Pipeline

  • cargo fmt --all ✅
  • cargo clippy --all-targets -- -D warnings ✅
  • cargo test --all ✅ (381 controller + 105 router + 26 integration tests)
  • cd cli && npm run lint && npm run typecheck && npm test && npm run build ✅
  • helm lint deploy/helm/azureclaw ✅

Examples and fixtures

All clawsandbox.yaml in examples/ (basic-agent,
confidential-agent, telegram-agent, demo-clawshield/*),
tests/compat/fixtures/null-provider-*.yaml, and tests/e2e/run.sh
updated to the new two-doc-per-sandbox shape (InferencePolicy then
ClawSandbox).

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

BREAKING in-place v1alpha1 schema edit (pre-release; no conversion
webhook). Inline inference and tool-policy config on `ClawSandbox` is
removed; the spec now carries same-namespace refs to dedicated
`InferencePolicy` and `ToolPolicy` CRDs which become the single source
of truth.

Schema:
- spec.inference (InferenceConfig) → REMOVED.
- spec.inferenceRef: { name } → NEW, required. References sibling
  InferencePolicy CR.
- spec.governance.toolPolicy (string profile name) → REMOVED.
- spec.governance.toolPolicyRef: { name } → NEW. Required when
  governance.enabled=true (CEL-enforced).
- New status reasons `InferencePolicyNotFound`,
  `ToolPolicyNotFound` — emitted on Degraded when a referenced
  CR is missing in the sandbox's namespace.
- Cross-namespace refs are not supported (Api::namespaced lookup;
  security invariant — see CHANGELOG).
- Printcolumn updated: `Model` → `InferencePolicy`.

Reconciler (controller/src/reconciler/mod.rs):
- Resolves InferencePolicy after isolation validation:
  - 404 → degrade(InferencePolicyNotFound).
  - empty .spec.inferenceRef.name → degrade(SpecInvalid).
  - other API error → 15s requeue.
  - Reads modelPreference.primary.deployment → OPENCLAW_MODEL +
    AZURE_OPENAI_DEPLOYMENT (degrade SpecInvalid if empty).
  - tokenBudget.{daily,perRequest}Tokens → casts to i64 env vars.
  - contentSafety.requirePromptShields (default true).
- When governance.enabled=true, resolves ToolPolicy:
  - 404 → degrade(ToolPolicyNotFound).
  - resolved metadata.name → tool_policy_profile string used
    everywhere previously read from governance.tool_policy
    (AGT_POLICY_PROFILE, agt-policy-{name} ConfigMap, include_str!
    selection between azureclaw-default.yaml / azureclaw-offload.yaml).

CLI:
- New cli/src/refs.ts: kebabRefName helper + buildInferencePolicy /
  buildToolPolicy emitters. `<sandbox>-inference` /
  `<sandbox>-toolpolicy` naming, DNS-1123 truncated to 63 chars.
- `azureclaw up` and `azureclaw add` emit a multi-doc bundle
  (InferencePolicy + optional ToolPolicy + ClawSandbox) applied as
  a single `kubectl apply` of a v1.List manifest.
- `azureclaw migrate from-kagent` always emits an
  `<sandbox>-inference` InferencePolicy (preserving kagent
  modelConfig as provenance annotation when set), and a synthetic
  `<sandbox>-toolpolicy` aggregator whenever governance is on.
- attest.ts POLICY_CR_KINDS recognizes both `inferenceRef` (S13) and
  legacy `inferencePolicyRef` shapes during the rollout window.

Helm CRD (deploy/helm/azureclaw/templates/crd.yaml):
- spec.required: ["runtime", "sandbox", "inferenceRef"].
- inferenceRef: { name } with DNS-1123 pattern + non-empty CEL.
- governance.toolPolicyRef: { name } with DNS-1123 pattern.
- governance x-kubernetes-validations: toolPolicyRef.name must be set
  when governance.enabled=true.

Tests:
- 381 controller tests passing (added LocalObjectRef round-trip
  tests; reuses the existing `crate::mcp_server::LocalObjectRef`
  type — same shape, identical semantics).
- 395 CLI tests passing (add.test.ts, from_kagent.test.ts updated).

Examples + fixtures: all clawsandbox.yamls in examples/ and
tests/compat/fixtures/null-provider-*.yaml updated to the new
two-doc shape; tests/e2e/run.sh updated.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@pallakatos
Pal Lakatos-Toth (pallakatos) force-pushed the phase2-s13-config-authority-refs branch from 664c1c3 to d5382ec Compare April 30, 2026 00:57
@pallakatos
Pal Lakatos-Toth (pallakatos) merged commit ef1ca03 into dev Apr 30, 2026
16 checks passed
Pal Lakatos-Toth (pallakatos) added a commit that referenced this pull request May 12, 2026
…#118)

BREAKING in-place v1alpha1 schema edit (pre-release; no conversion
webhook). Inline inference and tool-policy config on `ClawSandbox` is
removed; the spec now carries same-namespace refs to dedicated
`InferencePolicy` and `ToolPolicy` CRDs which become the single source
of truth.

Schema:
- spec.inference (InferenceConfig) → REMOVED.
- spec.inferenceRef: { name } → NEW, required. References sibling
  InferencePolicy CR.
- spec.governance.toolPolicy (string profile name) → REMOVED.
- spec.governance.toolPolicyRef: { name } → NEW. Required when
  governance.enabled=true (CEL-enforced).
- New status reasons `InferencePolicyNotFound`,
  `ToolPolicyNotFound` — emitted on Degraded when a referenced
  CR is missing in the sandbox's namespace.
- Cross-namespace refs are not supported (Api::namespaced lookup;
  security invariant — see CHANGELOG).
- Printcolumn updated: `Model` → `InferencePolicy`.

Reconciler (controller/src/reconciler/mod.rs):
- Resolves InferencePolicy after isolation validation:
  - 404 → degrade(InferencePolicyNotFound).
  - empty .spec.inferenceRef.name → degrade(SpecInvalid).
  - other API error → 15s requeue.
  - Reads modelPreference.primary.deployment → OPENCLAW_MODEL +
    AZURE_OPENAI_DEPLOYMENT (degrade SpecInvalid if empty).
  - tokenBudget.{daily,perRequest}Tokens → casts to i64 env vars.
  - contentSafety.requirePromptShields (default true).
- When governance.enabled=true, resolves ToolPolicy:
  - 404 → degrade(ToolPolicyNotFound).
  - resolved metadata.name → tool_policy_profile string used
    everywhere previously read from governance.tool_policy
    (AGT_POLICY_PROFILE, agt-policy-{name} ConfigMap, include_str!
    selection between azureclaw-default.yaml / azureclaw-offload.yaml).

CLI:
- New cli/src/refs.ts: kebabRefName helper + buildInferencePolicy /
  buildToolPolicy emitters. `<sandbox>-inference` /
  `<sandbox>-toolpolicy` naming, DNS-1123 truncated to 63 chars.
- `azureclaw up` and `azureclaw add` emit a multi-doc bundle
  (InferencePolicy + optional ToolPolicy + ClawSandbox) applied as
  a single `kubectl apply` of a v1.List manifest.
- `azureclaw migrate from-kagent` always emits an
  `<sandbox>-inference` InferencePolicy (preserving kagent
  modelConfig as provenance annotation when set), and a synthetic
  `<sandbox>-toolpolicy` aggregator whenever governance is on.
- attest.ts POLICY_CR_KINDS recognizes both `inferenceRef` (S13) and
  legacy `inferencePolicyRef` shapes during the rollout window.

Helm CRD (deploy/helm/azureclaw/templates/crd.yaml):
- spec.required: ["runtime", "sandbox", "inferenceRef"].
- inferenceRef: { name } with DNS-1123 pattern + non-empty CEL.
- governance.toolPolicyRef: { name } with DNS-1123 pattern.
- governance x-kubernetes-validations: toolPolicyRef.name must be set
  when governance.enabled=true.

Tests:
- 381 controller tests passing (added LocalObjectRef round-trip
  tests; reuses the existing `crate::mcp_server::LocalObjectRef`
  type — same shape, identical semantics).
- 395 CLI tests passing (add.test.ts, from_kagent.test.ts updated).

Examples + fixtures: all clawsandbox.yamls in examples/ and
tests/compat/fixtures/null-provider-*.yaml updated to the new
two-doc shape; tests/e2e/run.sh updated.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@pallakatos
Pal Lakatos-Toth (pallakatos) deleted the phase2-s13-config-authority-refs branch June 1, 2026 14:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant