Skip to content

Add agent compatibility checks for version-gated native settings #85

Description

@kelos-bot

🤖 Kelos Strategist Agent @gjkim42

Area: New Managed-Settings Types & CLI Extensions

Summary

Kanon can validate that kanon.yaml is structurally valid and can render Codex/Claude files, but it cannot answer a fleet question that will become more important as the schema grows:

Does the installed agent client on this machine actually support the native settings Kanon is about to render?

This is distinct from checking whether node, semgrep, or an MCP server binary exists. It is about the Codex/Claude clients themselves: their versions, native config scopes, and feature gates. If a shared Kanon repo uses a feature that older local agents ignore, treat differently, or require trust/setup for, kanon validate, render, diff, and apply currently still succeed.

Proposal: add an additive compatibility contract plus a kanon compat check command. The MVP should infer required agent features from the current config, optionally honor explicit minimum versions from kanon.yaml, probe installed codex / claude clients when available, and emit text/JSON diagnostics before settings are applied across a team or runner fleet.

Evidence from the current codebase

  • internal/core/types.go:11-18 defines the config as instructions, skills, mcp, hooks, and metadata. There is no requires, compatibility, agents, or feature-requirement section.
  • TargetOptions carries only KanonHome, UserHome, Project, Agent, and SourceLock (internal/core/types.go:104-110). It has no agent binary path, installed version, or capability data.
  • ValidateConfig checks schema version, referenced instruction/skill files, target names, MCP command-or-URL presence, hook names, and env references (internal/core/config.go:66-151). It never probes installed agent clients or validates feature availability.
  • validateTargets only accepts all, codex, and claude (internal/core/config.go:284-290). It does not distinguish feature subsets inside a target.
  • CLI validate calls only core.ValidateConfig plus source-lock warnings (internal/cli/root.go:106-128). Render/diff/apply reuse the same validation path (internal/cli/root.go:435-458).
  • The renderers emit version-sensitive native feature shapes unconditionally once the target matches. For example, hooksForAgent emits hook config for both targets (internal/core/render.go:355-392), codexMCPServers emits Codex-specific fields such as env_vars, bearer_token_env_var, tool allow/deny, and per-tool approval policies (internal/core/render.go:424-485), and claudeMCPServers emits Claude's .mcp.json shape (internal/core/render.go:488-536).

Net: Kanon knows which native files it will write, but not whether the local agent version will understand those files and fields.

External signal

Current agent-native configuration is explicitly featureful and moving quickly:

  • Codex's configuration reference documents both user and project config.toml, and says project-scoped config ignores machine-local provider/auth/profile/notification/telemetry keys. That is a target-scope compatibility rule Kanon should eventually encode rather than only relying on native startup warnings. Source: https://developers.openai.com/codex/config-reference
  • Codex's advanced config docs describe lifecycle hooks in hooks.json or inline [hooks], with project-local hooks only loading when the project .codex/ layer is trusted. Source: https://developers.openai.com/codex/config-advanced
  • Codex's hooks docs describe hook trust review and distinguish managed hooks from user/project hooks; managed hooks from requirements.toml sources are trusted by policy and cannot be disabled from the hook browser. Source: https://developers.openai.com/codex/hooks
  • Codex's changelog shows hooks reaching general availability in May 2026, which is exactly the kind of recent agent feature that can be present on some machines and absent on others. Source: https://developers.openai.com/codex/changelog
  • Claude Code's settings reference includes managed-only settings and explicitly says strictPluginOnlyCustomization requires Claude Code v2.1.82 or later; earlier versions ignore the key and keep loading user/project customizations. Source: https://code.claude.com/docs/en/settings
  • Claude's hooks reference now covers command, HTTP, prompt, agent, async, and MCP-tool hooks. Source: https://code.claude.com/docs/en/hooks

The key product signal: teams can now express high-impact controls in agent-native config, but those controls may be version- or scope-dependent. A central config manager should fail fast when a fleet machine cannot enforce what the source claims.

Proposed schema

Add an optional compatibility: block. It is not required for existing configs; absent means Kanon only infers feature requirements from the rendered config.

version: 1

compatibility:
  kanon: ">=0.0.0"          # optional, useful once Kanon has releases
  agents:
    claude:
      command: claude       # default: claude
      min_version: ">=2.1.82"
      features:
        - hooks
        - managed_customization_lockdown
        - project_mcp

    codex:
      command: codex        # default: codex
      features:
        - hooks
        - skills
        - mcp_tool_policies

Suggested Go shape:

type Config struct {
    Version       int                 `yaml:"version"`
    Instructions  Instructions        `yaml:"instructions"`
    Skills        []Skill             `yaml:"skills"`
    Compatibility CompatibilityConfig `yaml:"compatibility"`
    MCP           MCPConfig           `yaml:"mcp"`
    Hooks         []Hook              `yaml:"hooks"`
    Metadata      map[string]string   `yaml:"metadata"`
}

type CompatibilityConfig struct {
    Kanon  string                            `yaml:"kanon,omitempty"`
    Agents map[string]AgentCompatibilitySpec `yaml:"agents,omitempty"`
}

type AgentCompatibilitySpec struct {
    Command    string   `yaml:"command,omitempty"`
    MinVersion string   `yaml:"min_version,omitempty"`
    Features   []string `yaml:"features,omitempty"`
}

The explicit features list lets teams require an agent capability even before Kanon can infer it from a setting. min_version handles known cutoffs like Claude's strictPluginOnlyCustomization requirement.

CLI proposal

Add:

kanon compat check
kanon compat check --agent claude
kanon compat check --format json
kanon compat check --strict

Suggested text output:

claude  ok       2.1.183 satisfies >=2.1.82; features: hooks, project_mcp, managed_customization_lockdown
codex   warning  command "codex" not found; cannot verify inferred features: hooks, skills, mcp_tool_policies

Suggested JSON shape:

{
  "agents": [
    {
      "agent": "claude",
      "command": "claude",
      "status": "ok",
      "detectedVersion": "2.1.183",
      "minVersion": ">=2.1.82",
      "requiredFeatures": ["hooks", "project_mcp"],
      "requiredBy": ["hooks.repo-tests", "mcp.servers.github"],
      "warnings": [],
      "errors": []
    }
  ]
}

Behavior:

  • Load and validate config normally.
  • Infer required features from enabled settings selected by --agent and --project.
  • Merge inferred requirements with explicit compatibility.agents.<agent>.features.
  • Probe command --version or an agent-specific version command. If parsing is unreliable, report the raw version string and mark version comparison as unknown rather than guessing.
  • Exit non-zero when --strict is set and an installed client is missing, below the declared minimum, or known not to support an inferred required feature.
  • Keep the output content-free: no instruction bodies, headers, env values, or hook command contents in JSON.

Feature inference examples

Initial inference can be conservative and small:

Kanon setting Inferred feature
instructions.files targeting Codex codex.agents_md
instructions.files targeting Claude claude.claude_md
any enabled skills[] entry <agent>.skills
any enabled hooks[] entry <agent>.hooks
hook.async: true <agent>.async_hooks when target supports async hooks
any enabled MCP server <agent>.mcp
mcp.servers.*.enabled_tools, disabled_tools, default_approval, or tools targeting Codex codex.mcp_tool_policies
future native passthrough / managed-policy settings their specific native feature keys

Feature-to-minimum-version data should be explicit and sparse. If Kanon does not know a minimum version for a feature, it should still report the feature as required and say version enforcement is unknown. Avoid inventing unsupported version guarantees.

Why this matters strategically

  1. Fleet consistency: A central Kanon repo is only as strong as the oldest agent client in the fleet. Compatibility checks make drift visible before a setting silently fails to enforce.
  2. Security controls: Version-gated managed settings are risky when older clients ignore them. Claude's documented strictPluginOnlyCustomization cutoff is a concrete example.
  3. Faster support: When one machine behaves differently, kanon compat check --format json can show whether the local agent is missing the feature the source assumes.
  4. Safer future schema growth: Existing proposals for subagents, session UI, permissions, network policy, packs, and managed-policy artifacts all add native feature dependencies. A compatibility registry gives those features one place to declare requirements.

Why this is not a duplicate

I reviewed recent open generated-by-kelos issues and searched all issues for compatibility, minimum version, agent version, capability, and requirements overlap.

This is distinct from:

Suggested MVP scope

  1. Add CompatibilityConfig structs and validation for supported agent keys, feature-name syntax, and semver constraint syntax when present.
  2. Add a small feature inference helper that returns required features plus requiredBy references for the current config/agent/project selection.
  3. Add kanon compat check --format text|json --strict.
  4. Implement version probing for claude and codex with tolerant parsers and raw-output fallback.
  5. Seed a tiny feature registry with only well-supported facts, including Claude strictPluginOnlyCustomization >=2.1.82; leave unknown features as report-only.
  6. Add tests for explicit minimum version pass/fail, missing command handling, feature inference from hooks/MCP/skills, target filtering, JSON output, and unknown feature warnings.

Backward compatibility

  • Existing kanon.yaml files remain valid.
  • No render/apply output changes when compatibility: is absent.
  • The new command is additive.
  • kanon validate can remain static in the MVP; a later validate --compat flag can delegate to the same checker once teams trust the behavior.

Non-goals

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions