Skip to content

patch: Move category definitions to per-template .fips-template.yaml manifest #45

@rdwj

Description

@rdwj

Step 3 of #42. Larger lift than steps 1 and 2 — touches every template repo and changes the source of truth for patch metadata. Filing for design discussion before code.

Problem

Today the patch category lists live in src/fips_agents_cli/tools/patching.py as hardcoded constants:

  • MCP_FILE_CATEGORIES, AGENT_FILE_CATEGORIES
  • MCP_NEVER_PATCH, AGENT_NEVER_PATCH
  • get_categories_for_type() raises ValueError for gateway, ui, sandbox

Consequences:

Proposal

Each template repo ships a manifest at the comparison root declaring its own patch metadata:

# .fips-template.yaml — at the template root (or monorepo subdir root)
type: agent  # or mcp-server, gateway, ui, sandbox

patch:
  categories:
    chart:
      description: Helm chart templates
      patterns:
        - chart/templates/**/*
        - chart/Chart.yaml
      ask_before_patch: true
    evals:
      description: Eval harness
      patterns:
        - evals/__init__.py
        - evals/assertions.py
        - evals/discovery.py
        - evals/mock_factory.py
        - evals/run_evals.py
        - evals/README.md
      ask_before_patch: true
    claude:
      description: Claude Code slash commands and rules
      patterns:
        - .claude/commands/**/*
        - .claude/rules/**/*
      ask_before_patch: false
    # docs, build, ...

  never_patch:
    - src/agent.py
    - agent.yaml
    - chart/values.yaml
    - src/fipsagents/**
    - tools/**
    - examples/**
    - prompts/**
    - rules/**
    - skills/**
    - tests/**/*.py
    - README.md
    - pyproject.toml
    - .env*
    - .memoryhub.yaml

Loader behavior

_clone_template_for_patch already returns the comparison root. The patcher reads <root>/.fips-template.yaml after clone and uses it to drive check_for_updates and patch_category. When the manifest is absent (legacy templates, projects pinned to old commits), fall back to the current hardcoded constants.

Net effect

  • Each template owns the truth about what is patchable. Agent template adds a file → next patch check surfaces it without a CLI release.
  • gateway-template, ui-template, code-sandbox opt in by shipping a manifest. No new constants in the CLI.
  • MCP_FILE_CATEGORIES / AGENT_FILE_CATEGORIES become fallbacks, not source of truth.

Open design questions

  1. Where does the manifest live for monorepo templates? Inside the subdir (e.g. templates/agent-loop/.fips-template.yaml) is the obvious answer — it travels with the comparison root.
  2. Schema validation. Pydantic? jsonschema? tomlkit? YAML-based is consistent with agent.yaml and Helm values.yaml so YAML feels right.
  3. Versioning. Should the manifest declare a schema_version: 1 so the CLI can reject unfamiliar future schemas?
  4. Migration. Land the loader in a release that still ships the hardcoded fallbacks. Then update each template repo to ship the manifest. Then in a later major release we could drop the fallbacks — though there's no urgency.
  5. add integration. Should fips-agents add <modality> consult the manifest's never_patch to decide where it can write? Probably not — modality target paths are part of the modality spec, not the manifest. But worth thinking about.

Affected repos

  • fips-agents/fips-agents-cli — loader change, fallback retention, tests.
  • fips-agents/agent-template — ship .fips-template.yaml for both templates/agent-loop/ and templates/workflow/.
  • fips-agents/mcp-server-template — ship .fips-template.yaml.
  • fips-agents/gateway-template, fips-agents/ui-template, fips-agents/code-sandbox — ship manifest if/when patch support is added for those project types.

Suggested rollout

  1. Land patch: Fix coverage gaps in template categories (step 1 of #42) #43 (step 1: typo + missing patterns).
  2. Land step 2 (evals category) using the existing constants.
  3. Implement the manifest loader behind a feature gate, with the existing constants as the fallback.
  4. Add manifests to each template repo, one PR per repo.
  5. Once every supported template ships a manifest, the constants in tools/patching.py are technically dead — remove them in a major release.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions