Skip to content

patch: Read .fips-template.yaml manifest with fallback (closes loader part of #45)#48

Merged
rdwj merged 1 commit into
mainfrom
feat/45-template-manifest-loader
May 7, 2026
Merged

patch: Read .fips-template.yaml manifest with fallback (closes loader part of #45)#48
rdwj merged 1 commit into
mainfrom
feat/45-template-manifest-loader

Conversation

@rdwj
Copy link
Copy Markdown
Collaborator

@rdwj rdwj commented May 6, 2026

First slice of #45 — the CLI side. Templates can now ship a .fips-template.yaml at the comparison root declaring their own patch categories and never_patch list. The CLI prefers the manifest when present and well-formed; otherwise it falls back to the existing hardcoded constants.

Stacked on #46 (#44's evals work). Merge order: #43#46 → this PR.

What

  • _load_template_manifest(template_root) — reads .fips-template.yaml, validates schema_version: 1, returns the parsed dict or None for any unrecoverable case (with a user-visible warning when the file is present but unusable).
  • _categories_from_manifest(manifest) — translates the manifest into the (categories_dict, never_patch_list) shape the rest of the patcher already consumes. Fills in defaults for description and ask_before_patch. Returns None on structurally bad input.
  • _resolve_categories(template_root, template_info) — manifest first, fallback to constants by template.type. This is the only new entry point the rest of the file calls.
  • check_for_updates and patch_category now use _resolve_categories(template_root, ...) after cloning. patch_category keeps a pre-clone fast-fail against the built-in category set so typos and cross-type misuse don't pay for a clone.

Schema

schema_version: 1
patch:
  categories:
    <name>:
      description: <str>       # optional, defaults to <name>
      patterns: [<glob>, ...]  # required
      ask_before_patch: <bool> # optional, defaults to false
  never_patch: [<glob>, ...]   # optional, defaults to []

Out of scope (deliberate)

  • Shipping manifests in template repos. That's one PR per template repo, tracked by patch: Move category definitions to per-template .fips-template.yaml manifest #45 still. This PR adds the loader; the templates can opt in incrementally.
  • Dynamic Click subcommand registration. A manifest declaring a brand-new category like helm-tests will show up in patch check and patch all, but patch helm-tests won't exist as a CLI verb until we add dynamic registration. The well-known categories (generators, core, docs, build, chart, claude, evals) are unchanged from the user's POV.
  • Matcher fix from patch: NEVER_PATCH "README.md" pattern matches nested READMEs too #47 (bare README.md matching nested READMEs). Filed separately; manifest loader doesn't touch the matcher.

Test plan

  • 19 new unit + integration tests covering loader, translation, resolver, and the end-to-end patch check path with a manifest-bearing fake template.
  • Full suite passes: 309 passed.
  • black src tests clean.
  • ruff check src tests clean.
  • E2E sanity: scaffolded a real agent project against the live fips-agents/agent-template (no manifest yet) — fallback path returns the same drift report as before this change.

Closes the loader portion of #45. Templates can now ship a
.fips-template.yaml at the comparison root (template root for
standalone repos, monorepo subdir root for agent-template) declaring
their own patch categories and never_patch list. The CLI prefers
the manifest when present and well-formed; otherwise it falls back
to the existing hardcoded constants keyed by template.type.

Schema (schema_version: 1):

    schema_version: 1
    patch:
      categories:
        <name>:
          description: <str>      # optional, defaults to <name>
          patterns: [<glob>, ...] # required
          ask_before_patch: <bool># optional, defaults to false
      never_patch: [<glob>, ...]  # optional, defaults to []

Loader behavior:
- File missing → silent fallback (legacy templates).
- YAML malformed / not a mapping → warn, fall back.
- schema_version absent or unsupported → warn, fall back.
- Manifest valid but missing required fields → warn, fall back.

Limitations of this slice:
- A manifest can override patterns / ask_before_patch / never_patch
  for the well-known categories (generators, core, docs, build,
  chart, claude, evals). It can also declare brand-new categories,
  which surface in `patch check` and `patch all`, but `patch <new>`
  has no Click subcommand registered for it. Dynamic subcommand
  registration is a follow-up.
- patch_category() now clones before re-validating the category in
  the manifest. The pre-clone fast-fail still rejects categories
  that are not in the project type's built-in set, so typos and
  cross-type misuse don't pay for a clone.
- get_categories_for_type() raises for gateway / ui / sandbox the
  same as before; those project types only become patchable once
  their template ships a manifest.

Tests:
- Unit tests for _load_template_manifest (present, absent, bad YAML,
  bad shape, bad / missing schema_version).
- Unit tests for _categories_from_manifest (defaults, validation,
  rejection of bad shapes).
- Unit tests for _resolve_categories (manifest beats constants;
  fallback paths; opt-in for gateway / ui / sandbox).
- Integration test exercising `patch check` with a manifest-bearing
  fake template, asserting the manifest's category names override
  the built-in agent categories.

Stacks on #44.

Assisted-by: Claude Code (Opus 4.7)
@rdwj rdwj force-pushed the feat/45-template-manifest-loader branch from 6edb7a1 to 6a70481 Compare May 7, 2026 00:10
@rdwj rdwj merged commit a0face7 into main May 7, 2026
@rdwj rdwj deleted the feat/45-template-manifest-loader branch May 7, 2026 00:10
rdwj added a commit to fips-agents/gateway-template that referenced this pull request May 7, 2026
Without this manifest, the fips-agents-cli refuses to run
`fips-agents patch` against gateway projects — its
`get_categories_for_type` raises for gateway / ui / sandbox project
types because no hardcoded category set exists for them. The
presence of this file is what makes the patch flow work for
projects scaffolded from this template.

Schema: schema_version: 1, with three categories (chart, docs,
build) and a 13-entry never_patch list separating
template-managed scaffolding from the user's Go source, deploy
values, and helper scripts.

Categories deliberately match the names of CLI subcommands the user
already has (`fips-agents patch chart`, `patch docs`, `patch build`)
so a future agent / mcp / gateway user has the same muscle memory
across project types.

Companion to fips-agents/fips-agents-cli#48 (the loader). Older CLI
installs that don't know about .fips-template.yaml will simply
ignore the file — nothing breaks.

Assisted-by: Claude Code (Opus 4.7)
rdwj added a commit to fips-agents/ui-template that referenced this pull request May 7, 2026
Without this manifest, the fips-agents-cli refuses to run
`fips-agents patch` against UI projects — its
`get_categories_for_type` raises for gateway / ui / sandbox project
types because no hardcoded category set exists for them. The
presence of this file is what makes the patch flow work for
projects scaffolded from this template.

Schema: schema_version: 1, with three categories (chart, docs,
build) and a 9-entry never_patch list separating template-managed
scaffolding from the user's Go source, web content, and deploy
values.

Companion to fips-agents/fips-agents-cli#48 (the loader). Older CLI
installs that don't know about .fips-template.yaml will simply
ignore the file — nothing breaks.

Assisted-by: Claude Code (Opus 4.7)
rdwj added a commit that referenced this pull request May 7, 2026
- Add v0.12.0 changelog entry (manifest loader, evals category, MCP
  claude category, never-patch matcher fix, pattern gap fills).
- Update Patch Commands section: list .fips-template.yaml manifest
  support, add Gateway/UI category table, refresh per-type tables to
  match the actual category surface after #43, #46, #48, #49.
- Expand the user-customized-files paragraph to cover the new
  AGENT_NEVER_PATCH entries and the gateway/UI never-patch list.

Assisted-by: Claude Code (Opus 4.7)
rdwj added a commit to fips-agents/code-sandbox that referenced this pull request May 7, 2026
Without this manifest, fips-agents-cli refuses to run `fips-agents
patch` against sandbox projects — the CLI's hardcoded fallback has
no built-in category set for the 'sandbox' project type, so it now
emits a friendly ✗ error pointing here (see
fips-agents/fips-agents-cli#50). The presence of this file is what
makes the patch flow work for projects scaffolded from this template.

Schema: schema_version: 1, three categories (chart, docs, build) and
a 10-entry never_patch list separating template-managed scaffolding
from the user's runtime, tests, deploy values, and repo settings.

Conservative defaults — sandbox/** (the runtime) and tests/** are in
never_patch on the agent-template precedent: users may have
customized these and we don't silently overwrite them. If we later
decide users should track upstream runtime changes via patch, that's
a follow-up that adds a 'runtime' category covering sandbox/**/*.py
with ask_before_patch: true.

Companion to fips-agents/fips-agents-cli#48 (the loader, shipped in
v0.12.0). Older CLI installs ignore the file — non-breaking.

Assisted-by: Claude Code (Opus 4.7)
rdwj added a commit to fips-agents/ui-template that referenced this pull request May 7, 2026
* Add .fips-template.yaml to opt into fips-agents patch flow

Without this manifest, the fips-agents-cli refuses to run
`fips-agents patch` against UI projects — its
`get_categories_for_type` raises for gateway / ui / sandbox project
types because no hardcoded category set exists for them. The
presence of this file is what makes the patch flow work for
projects scaffolded from this template.

Schema: schema_version: 1, with three categories (chart, docs,
build) and a 9-entry never_patch list separating template-managed
scaffolding from the user's Go source, web content, and deploy
values.

Companion to fips-agents/fips-agents-cli#48 (the loader). Older CLI
installs that don't know about .fips-template.yaml will simply
ignore the file — nothing breaks.

Assisted-by: Claude Code (Opus 4.7)

* fix: Hide drop overlay when [hidden] attribute is set

The `.drop-overlay { display: flex }` rule overrode the user-agent's
`[hidden] { display: none }`, so the JS-toggled `hidden` property had no
visual effect and the dashed drop zone was permanently rendered over the
input row.

Closes #28

Assisted-by: Claude Code (Opus 4.7)
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