fips-agents patch check and the per-category subcommands rely on hardcoded glob patterns in src/fips_agents_cli/tools/patching.py (MCP_FILE_CATEGORIES, AGENT_FILE_CATEGORIES, *_NEVER_PATCH). Those patterns have drifted behind what the template repos actually ship. A patch check against a current agent project reports "up to date" for several files that have demonstrably changed in the template.
This issue is part audit, part proposal.
Audit — files shipped by each template that no patch category covers
Tree comparisons done against:
fips-agents/agent-template (templates/agent-loop/ and templates/workflow/)
fips-agents/mcp-server-template
- local
gateway-template, ui-template peers
Agent / workflow template
Not surfaced by patch check — silently invisible:
.claude/rules/agent-development.md (and .claude/rules/workflow-development.md). The claude category globs .claude/commands/**/* only.
evals/__init__.py, evals/assertions.py, evals/discovery.py, evals/mock_factory.py, evals/run_evals.py, evals/README.md — the entire eval harness.
prompts/system.md, rules/citation_required.md, skills/summarize/SKILL.md — starter content. These are user-customizable and probably want to live in AGENT_NEVER_PATCH rather than a category, but they need to live somewhere.
.containerignore, .gitignore, .memoryhub.yaml — root dotfiles.
tools/.gitkeep, src/__init__.py — minor.
User-customized paths that lack defense-in-depth in AGENT_NEVER_PATCH (today they're not in any category, so patch leaves them alone, but a future pattern broadening could clobber add-injected files):
tools/** (target of fips-agents add code-executor)
examples/** (target of fips-agents add vision)
prompts/**, rules/**, skills/**
MCP server template
Two real bugs:
- Typo in
core patterns at tools/patching.py:32: \"src/*/__ init__.py\" has a literal space between __ and init__. The pattern matches nothing — package __init__.py files are never offered as patches.
- No
claude category for MCP, but the MCP template ships .claude/commands/*.md (create-tools.md, deploy-mcp.md, exercise-tools.md, implement-mcp-item.md, plan-tools.md, update-docs.md, write-system-prompt.md). Updates to those slash commands are unreachable via patch.
Other gaps:
core patterns miss src/main.py (the entry point) and src/core/__init__.py.
docs patterns miss AGENTS.md, CONTRIBUTING.md, DEVELOPMENT_PROCESS.md, OPENSHIFT_DEPLOYMENT.md.
build patterns miss .dockerignore, .gitignore, .gitleaks.toml, .github/CODEOWNERS.
LICENSE and requirements.txt are not in any bucket.
Gateway / UI templates
get_categories_for_type() raises ValueError for gateway, ui, sandbox. So fips-agents patch check is non-functional for those project types today. The Go templates have an obvious shape (chart/, Makefile, Containerfile, cmd/, internal/, go.mod, go.sum) and could support patching with categories analogous to the agent template. Worth deciding whether to add now or defer.
Patch subcommand review
commands/patch.py registers generators, core, docs, build, chart, claude, all, check unconditionally. When a subcommand is invalid for the current project type, patch_category() returns a clear "Available: ..." error. That's fine and matches the documented behavior in CLAUDE.md. No subcommand changes are needed beyond whatever new categories we add.
If we add new categories per the audit above:
- Agent / workflow gain:
evals (the harness; ask before patch).
- MCP gains:
claude (slash commands; safe to overwrite).
Proposal — ship a .fips-template.yaml in each template repo
The hardcoded constants in tools/patching.py are awkward because:
- The CLI repo and the template repos drift independently. A new file added to a template doesn't show up in
patch check until someone updates the CLI and ships a release.
- Adding
gateway / ui / sandbox patch support means more constants and more branching in get_categories_for_type().
- The current "never patch" lists are easy to forget when the template grows.
A small manifest file shipped at the template root (or in the monorepo subdir) would make patch data-driven:
# .fips-template.yaml
type: agent
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*
Loader behavior: _clone_template_for_patch already returns the comparison root; the patcher reads <root>/.fips-template.yaml after clone. Fall back to the current hardcoded constants when the manifest is absent (legacy templates or projects pinned to old commits).
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.
- The CLI's
MCP_FILE_CATEGORIES / AGENT_FILE_CATEGORIES become fallbacks, not the source of truth.
Suggested split
Three commits / PRs, in order of risk:
- Fix the typo and the missing patterns in the existing constants (
src/*/__ init__.py → src/*/__init__.py, add .claude/rules/**/* to agent claude, expand agent AGENT_NEVER_PATCH, add MCP claude category, fill in MCP docs / build / core gaps). Lowest risk, immediate user value.
- Add an
evals category for agent / workflow. Touches the agent template by way of ask_before_patch UX, but no template-side change required.
- Move to per-template manifests. Larger lift — touches every template repo. Probably worth a design issue of its own first.
Steps 1 and 2 unblock the immediate gap. Step 3 is the correct long-term shape but is not blocking.
fips-agents patch checkand the per-category subcommands rely on hardcoded glob patterns insrc/fips_agents_cli/tools/patching.py(MCP_FILE_CATEGORIES,AGENT_FILE_CATEGORIES,*_NEVER_PATCH). Those patterns have drifted behind what the template repos actually ship. Apatch checkagainst a current agent project reports "up to date" for several files that have demonstrably changed in the template.This issue is part audit, part proposal.
Audit — files shipped by each template that no patch category covers
Tree comparisons done against:
fips-agents/agent-template(templates/agent-loop/andtemplates/workflow/)fips-agents/mcp-server-templategateway-template,ui-templatepeersAgent / workflow template
Not surfaced by
patch check— silently invisible:.claude/rules/agent-development.md(and.claude/rules/workflow-development.md). Theclaudecategory globs.claude/commands/**/*only.evals/__init__.py,evals/assertions.py,evals/discovery.py,evals/mock_factory.py,evals/run_evals.py,evals/README.md— the entire eval harness.prompts/system.md,rules/citation_required.md,skills/summarize/SKILL.md— starter content. These are user-customizable and probably want to live inAGENT_NEVER_PATCHrather than a category, but they need to live somewhere..containerignore,.gitignore,.memoryhub.yaml— root dotfiles.tools/.gitkeep,src/__init__.py— minor.User-customized paths that lack defense-in-depth in
AGENT_NEVER_PATCH(today they're not in any category, so patch leaves them alone, but a future pattern broadening could clobberadd-injected files):tools/**(target offips-agents add code-executor)examples/**(target offips-agents add vision)prompts/**,rules/**,skills/**MCP server template
Two real bugs:
corepatterns attools/patching.py:32:\"src/*/__ init__.py\"has a literal space between__andinit__. The pattern matches nothing — package__init__.pyfiles are never offered as patches.claudecategory for MCP, but the MCP template ships.claude/commands/*.md(create-tools.md,deploy-mcp.md,exercise-tools.md,implement-mcp-item.md,plan-tools.md,update-docs.md,write-system-prompt.md). Updates to those slash commands are unreachable via patch.Other gaps:
corepatterns misssrc/main.py(the entry point) andsrc/core/__init__.py.docspatterns missAGENTS.md,CONTRIBUTING.md,DEVELOPMENT_PROCESS.md,OPENSHIFT_DEPLOYMENT.md.buildpatterns miss.dockerignore,.gitignore,.gitleaks.toml,.github/CODEOWNERS.LICENSEandrequirements.txtare not in any bucket.Gateway / UI templates
get_categories_for_type()raisesValueErrorforgateway,ui,sandbox. Sofips-agents patch checkis non-functional for those project types today. The Go templates have an obvious shape (chart/,Makefile,Containerfile,cmd/,internal/,go.mod,go.sum) and could support patching with categories analogous to the agent template. Worth deciding whether to add now or defer.Patch subcommand review
commands/patch.pyregistersgenerators,core,docs,build,chart,claude,all,checkunconditionally. When a subcommand is invalid for the current project type,patch_category()returns a clear "Available: ..." error. That's fine and matches the documented behavior inCLAUDE.md. No subcommand changes are needed beyond whatever new categories we add.If we add new categories per the audit above:
evals(the harness; ask before patch).claude(slash commands; safe to overwrite).Proposal — ship a
.fips-template.yamlin each template repoThe hardcoded constants in
tools/patching.pyare awkward because:patch checkuntil someone updates the CLI and ships a release.gateway/ui/sandboxpatch support means more constants and more branching inget_categories_for_type().A small manifest file shipped at the template root (or in the monorepo subdir) would make patch data-driven:
Loader behavior:
_clone_template_for_patchalready returns the comparison root; the patcher reads<root>/.fips-template.yamlafter clone. Fall back to the current hardcoded constants when the manifest is absent (legacy templates or projects pinned to old commits).Net effect:
patch checksurfaces it without a CLI release.gateway-template,ui-template,code-sandboxopt in by shipping a manifest.MCP_FILE_CATEGORIES/AGENT_FILE_CATEGORIESbecome fallbacks, not the source of truth.Suggested split
Three commits / PRs, in order of risk:
src/*/__ init__.py→src/*/__init__.py, add.claude/rules/**/*to agentclaude, expand agentAGENT_NEVER_PATCH, add MCPclaudecategory, fill in MCPdocs/build/coregaps). Lowest risk, immediate user value.evalscategory for agent / workflow. Touches the agent template by way ofask_before_patchUX, but no template-side change required.Steps 1 and 2 unblock the immediate gap. Step 3 is the correct long-term shape but is not blocking.