Skip to content

feat(catalog_skills): add catalog generation, analysis, editing, and diff/changelog skills - #5365

Open
Venu-p1 wants to merge 12 commits into
dell:stagingfrom
Venu-p1:feature/catalog-skill-all-stories
Open

Venu-p1 wants to merge 12 commits into
dell:stagingfrom
Venu-p1:feature/catalog-skill-all-stories

Conversation

@Venu-p1

@Venu-p1 Venu-p1 commented Sep 27, 2026 •

Copy link
Copy Markdown
Collaborator

PR Title

feat(catalog_skills): add catalog generation, analysis, editing, and diff/changelog skills

PR Description

Description of the Solution

Implements a comprehensive suite of AI skills for catalog management under ER-BSM-001, including master reference file, catalog generation, impact/compatibility analysis, catalog editing with pre-edit gate, and reversible diff/changelog engine. Adds Python tooling for catalog diff/patch operations and fixes schema validation issues.

Related Issue

Changes

Component (src/build_stream/ai_skills/master_reference)

  • Added master_reference_file.md with 8 Appendix A tables (Selection Catalogue, Node-Role, Functional-Layer Composition, Stack-Storage Compatibility, Package Source Defaults, Pinned Version, Supported Hardware, Constraint/Co-Requisite)
  • Added SKILL.md implementing FR-2 Selection Catalogue support_status gate as channel-agnostic decision procedure

Component (src/build_stream/ai_skills/catalog_generation)

  • Added SKILL.md implementing FR-1.1 and FR-2 with Appendix B selection interview, master-reference gate application, storage filtering, and schema validation via existing CLI
  • Added shared/connectivity_layer.md for FR-3 online/offline fallback procedure

Component (src/build_stream/ai_skills/analysis)

  • Added impact_analysis.md for multi-tier operational impact analysis (package/role/cluster/user) with severity rubric and evidence tagging
  • Added compatibility_analysis.md for package/version compatibility checking against Red Hat Compatibility Matrix with disclosed fallback
  • Added trusted_source_policy.md for FR-3 trusted-source restrictions and NFR-4/Req-SEC-I-5 audit-logging contract

Component (src/build_stream/ai_skills/catalog_editing)

  • Added edit_catalog.md for single-catalog editing (add/remove packages, pin versions, correct metadata) reusing catalog_manager.py commands
  • Added bulk_edit_catalog.md for cross-catalog bulk edits with per-catalog schema-validation failure isolation
  • Added pre_edit_gate.md for shared approve/decline/skip orchestration with analysis integration

Component (src/build_stream/ai_skills/diff_changelog)

  • Added changelog_generator.md for invoking diff/changelog CLI via channel-agnostic skill instructions

Component (src/repo_manager/plugins/module_utils/catalog)

  • Added differ.py implementing deterministic op-list diff/patch engine with reversibility invariant verification
  • Added report_renderer.py for human-readable changelog and HTML report generation with compatibility warnings
  • Modified catalog_manager.py to add diff subcommand and implement validate-before-write for add/delete commands
  • Added templates/changelog_report.html.j2 for rich HTML changelog rendering

Component (src/repo_manager/schemas)

  • Modified catalog_schema.json to allow schema_version property, fixing validation failures for 22 shipped catalogs

Component (.gitignore)

  • Modified to exclude AI skills runtime audit logs (degraded_mode_audit.log, pre_edit_gate_audit.log)

Files Changed

File Change Type Description
.gitignore Modified Added AI skills runtime audit log exclusions
src/build_stream/ai_skills/analysis/compatibility_analysis.md Added Compatibility analysis skill for package/version checking
src/build_stream/ai_skills/analysis/impact_analysis.md Added Multi-tier operational impact analysis skill
src/build_stream/ai_skills/analysis/trusted_source_policy.md Added Trusted source policy and audit-logging contract
src/build_stream/ai_skills/catalog_editing/bulk_edit_catalog.md Added Cross-catalog bulk editing skill
src/build_stream/ai_skills/catalog_editing/edit_catalog.md Added Single-catalog editing skill
src/build_stream/ai_skills/catalog_editing/pre_edit_gate.md Added Shared pre-edit approval orchestration
src/build_stream/ai_skills/catalog_generation/SKILL.md Added Catalog generation skill with selection interview
src/build_stream/ai_skills/diff_changelog/changelog_generator.md Added Diff/changelog skill instructions
src/build_stream/ai_skills/master_reference/SKILL.md Added Selection Catalogue support_status gate
src/build_stream/ai_skills/master_reference/master_reference_file.md Added Master reference file with 8 Appendix A tables
src/build_stream/ai_skills/shared/connectivity_layer.md Added Online/offline fallback procedure
src/repo_manager/plugins/module_utils/catalog/catalog_manager.py Modified Added diff subcommand, validate-before-write for add/delete
src/repo_manager/plugins/module_utils/catalog/differ.py Added Reversible diff/patch engine
src/repo_manager/plugins/module_utils/catalog/report_renderer.py Added Changelog and HTML report renderer
src/repo_manager/plugins/module_utils/catalog/templates/changelog_report.html.j2 Added HTML changelog report template
src/repo_manager/schemas/catalog_schema.json Modified Added schema_version property to fix validation

Testing

  • Verified catalog generation skill validates output against existing catalog_manager.py validate CLI
  • Verified impact analysis with real RHEL 10.2 BaseOS/AppStream repos (dnf repoquery --whatrequires iproute)
  • Verified diff/changelog engine against real RHEL 10.0/10.2 service_k8s_x86_64 sample catalogs (198-operation forward/reverse diff)
  • Verified catalog editing skills end-to-end on real catalog (adding curl to service_k8s_x86_64.json 10.2)
  • Verified validate-before-write logic with MD5 checksum before/after for schema error scenarios
  • Verified reversible diff invariant: current + forward_diff == future, future + reverse_diff == current

Backward Compatibility

  • No breaking changes to existing catalog_manager.py commands
  • Schema change (adding schema_version) is additive and backward compatible
  • New skills are additive and do not modify existing catalog formats
  • Validate-before-write change preserves existing behavior when validation passes or no --schema is given

Suggested Reviewers

Reviewer Review Focus
@abhishek-sa1
@VenkateswaraVatam
@RvishankarOMnia
@snarthan
@Rajeshkumar-s2

Adds the FR-1.0 master reference file (8 Appendix A tables: Selection
Catalogue, Node-Role, Functional-Layer Composition, Stack-Storage
Compatibility, Package Source Defaults, Pinned Version, Supported
Hardware, Constraint/Co-Requisite), derived by hand from
src/main/samples/catalogs/**/*.json and
src/repo_manager/input/repo_manager_config.yml (plus
src/repo_manager's expected_versions map for AMD/ROCm and BeeGFS
planned-status evidence). Every row carries support_status and
file-level provenance.

Adds SKILL.md: the shared FR-2 Selection Catalogue support_status
gate, written as a channel-agnostic decision procedure rather than
code, so a browser-based AI assistant (FR-5.1) can apply it without
executing Python. Catalog Generation, Catalog Editing's Pre-Edit
Gate, and the Analysis skills read master_reference_file.md and
follow SKILL.md directly.

Story: ER-BSM-001-master-reference-file
Signed-off-by: venu <236371043+Venu-p1@users.noreply.github.com>
Every shipped sample catalog under src/main/samples/catalogs/**/*.json
carries catalog.schema_version (integer, currently 2), but
catalog_schema.json did not declare that property while using
additionalProperties: false at the catalog level. As a result all 22
shipped catalogs failed catalog_manager.py's validate command against
their own schema for this reason alone.

Discovered while implementing ER-BSM-001-catalog-generation-skill,
whose acceptance criteria require the skill's generated output to
validate against this schema using the existing catalog_manager.py
validate CLI (no new schema-validation code is introduced by that
skill).

Story: ER-BSM-001-catalog-generation-skill
Signed-off-by: venu <236371043+Venu-p1@users.noreply.github.com>
…ivity layer

Adds SKILL.md: a channel-agnostic decision procedure implementing
FR-1.1 and FR-2 of ER-BSM-001-nersc-ai-skills-catalog-authoring. It
runs the Appendix B selection interview in dependency order, applies
the master-reference Selection Catalogue gate at every decision point,
filters storage options by the Stack-Storage Compatibility table with
default pre-selection, rejects Kubernetes+aarch64, expands the
Functional-Layer Composition table into concrete functional layers,
resolves package sources/versions from A.5/A.6 with no-fabrication
handling for unresolved packages, and validates output by shelling out
to the existing catalog_manager.py validate CLI (no new schema_gate.py
file, per user direction).

Adds shared/connectivity_layer.md: the FR-3 online/offline fallback
procedure (prefer Red Hat Compatibility Matrix / upstream docs / live
package repos / local RPM repos; disclose fallback to master reference
file on timeout/unreachable/malformed data). Packaged as a single
shared instructions file referenced by this skill and reusable as-is
by the future ER-BSM-001-analysis-skills Story, per that Story's
resolved Open Question.

Story: ER-BSM-001-catalog-generation-skill
Signed-off-by: venu <236371043+Venu-p1@users.noreply.github.com>
…ills

Adds impact_analysis.md: traces functional-layer-to-package references
within a single catalog (direct blast radius), then attempts an
online transitive-dependency lookup via the shared connectivity layer,
falling back to catalog/master-reference-only scope with explicit
disclosure when unavailable (FR-3.1).

Adds compatibility_analysis.md: cross-references a package/version
against the Red Hat Compatibility Matrix and upstream documentation
when reachable (citing the specific source), falling back to A.1/A.6/
A.8 master-reference constraints only, with disclosure, when
unavailable (FR-3.2).

Adds trusted_source_policy.md: the shared FR-3 trusted-source-
restriction fragment both skills reference (never an open-ended web
search or unofficial mirror; report unresolved rather than broaden the
search), plus the NFR-4/Req-SEC-I-5 audit-logging contract -- a plain
text append to analysis/degraded_mode_audit.log when file-system
access is available, disclosure-text-only otherwise. No new Python.

Story: ER-BSM-001-analysis-skills
Signed-off-by: venu <236371043+Venu-p1@users.noreply.github.com>
src/build_stream/ai_skills/analysis/degraded_mode_audit.log is an
append-only operational artifact written by the analysis skills per
analysis/trusted_source_policy.md's audit-logging contract, not
source content.

Story: ER-BSM-001-analysis-skills
Signed-off-by: venu <236371043+Venu-p1@users.noreply.github.com>
… impact

Rewrites impact_analysis.md per the post-review FR-1 Enhancement
(R1-R8):

- R1: attempt local dnf metadata, then the package's own repo, then
  upstream docs, before falling back to the master reference file --
  "absent from A.6" is no longer a reason to stop early.
- R2: distinguish "removed from the catalog" from "actually removed
  from a built node" when another catalog package still requires it.
- R3: accept a target at the package, group, functional-layer, or OS
  level.
- R4/R5: four impact tiers (package/role/cluster/user), each tagged
  with its evidence class (repo-metadata/upstream-doc/catalog/inferred).
- R6: pinned-vs-latest version comparison when no pin exists.
- R7: Critical/High/Medium/Low severity rubric.
- R8: customer-facing summary leads the report.

Also updates the two shared fragments both analysis skills depend on:
- shared/connectivity_layer.md: clarifies the fallback trigger is an
  actual lookup failure, never merely "absent from one table"; notes
  the local Omnia-repo read as reachability under the existing "local
  system RPM repositories" class, not a new source class.
- analysis/trusted_source_policy.md: adds the architecture-mismatch
  operator-choice flow and two new audit-log reason= values
  (arch-mismatch, operator-declined-proxy).

Real reproduction on this host's subscribed RHEL 10.2 BaseOS/AppStream
repos (dnf repoquery --whatrequires iproute) motivated this change and
is used as the rewritten worked example.

Story: ER-BSM-001-analysis-skills
Signed-off-by: venu <236371043+Venu-p1@users.noreply.github.com>
…g engine

Implements the Semantic Catalog Diff and Human-Readable Changelog
Story (ER-BSM-001-diff-changelog-skill, FR-4.1/FR-4.2):

- differ.py: deterministic op-list diff/patch engine. build_ops()
  computes a self-contained forward or reverse op-list purely from two
  Schema 2.0 catalogs; apply_patch() applies one; diff_catalogs()
  computes both directions and verifies the reversibility invariant
  (current + forward_diff == future, future + reverse_diff ==
  current) exactly, raising ReversibilityError rather than returning
  a best-effort result if it doesn't hold. Rejects legacy Schema 1.0
  (PascalCase 'Catalog' root) input with an actionable error.
- report_renderer.py: builds a human-readable summary from the
  forward diff, a plain-English changelog, and (via Jinja2, optional)
  a rich HTML report -- always a separate artifact from the
  machine-readable diff, never merged into it. Implements the two
  compatibility/dependency warnings this Story's offline scope
  actually supports, from the master reference file's A.8 table:
  CON-004 (Kubernetes RPM/image/repo version-pin agreement) and
  CON-007 (shared-group removal affecting another functional layer).
- catalog_manager.py: new `diff` subcommand wiring the above together,
  reusing the existing schema-validation gate (validator.py) for the
  schema-invalid-catalog rejection scenario.
- diff_changelog/changelog_generator.md: channel-agnostic skill
  instructions that invoke the CLI above rather than hand-diffing
  catalogs, following the same "reuse an existing tool via CLI" pattern
  as the catalog-generation Story's schema-validation step.

Verified against the real shipped RHEL 10.0/10.2 service_k8s_x86_64
sample catalogs: 198-operation forward/reverse diff pair reconstructs
both catalogs exactly; identical catalogs produce an empty diff pair
(not an error); a synthetic kubelet minor-version bump correctly
triggers CON-004.

Story: ER-BSM-001-diff-changelog-skill
Signed-off-by: venu <236371043+Venu-p1@users.noreply.github.com>
cmd_add and cmd_delete wrote the mutated catalog to disk unconditionally,
then ran schema validation only afterward for reporting -- an invalid
edit was already persisted to the file by the time the [ERROR] lines
printed. Reorder both commands to validate the in-memory result first
and only write when there are no schema errors (unchanged behavior when
no --schema is given, or when validation passes/only has warnings).

Found while assessing whether ER-BSM-001-catalog-editing-skill's FR-1
("the skill SHALL reject the edit ... AND the catalog file SHALL remain
unmodified") could reuse these existing commands -- as written, they
could not have satisfied that requirement.

Verified: upsert_packages() + validate_catalog() on a package with an
empty sources list produces schema errors, and the reordered write-only-
if-no-errors logic leaves the target file's content byte-for-byte
unchanged (MD5 verified before/after).

Story: ER-BSM-001-catalog-editing-skill
Signed-off-by: venu <236371043+Venu-p1@users.noreply.github.com>
Implements ER-BSM-001-catalog-editing-skill (FR-1.2, FR-1.3, FR-6.1,
FR-5.1):

- edit_catalog.md: single-catalog editing (add/remove a package, pin
  a version, correct metadata), reusing catalog_manager.py's add/
  delete commands (now validate-before-write). Verified end-to-end on
  a real catalog: adding curl to service_k8s_x86_64.json (10.2) lands
  it in the correct group with the correct OS-version pin, and every
  other package/group/functionallayer entry compares dict-equal to
  the pre-edit catalog.
- bulk_edit_catalog.md: cross-catalog bulk edits with per-catalog
  schema-validation failure isolation. For edits add/delete already
  covers, isolation is free (each catalog is a separate read-validate-
  write cycle). For structural field edits with no dedicated CLI verb
  (e.g. a base_os group's os_version bump), documents and verifies the
  same validate-before-write pattern directly via the existing
  catalog_io/validator functions. Verified with two real catalogs, one
  deliberately missing a required field: the valid one's os_version
  updates on disk, the invalid one is left byte-for-byte unmodified
  (MD5-verified) with its specific violation reported.
- pre_edit_gate.md: the shared approve/decline/skip orchestration both
  editing skills call before applying anything (FR-6.1 has no apply
  path that skips this). Written as channel-agnostic instructions, not
  a Python state machine -- this is conversational orchestration
  (run analysis, present findings, wait for approval), not a
  deterministic invariant like the diff engine. Covers per-catalog
  differentiated flagging for bulk edits and wires to
  ER-BSM-001-analysis-skills (Impact/Compatibility Analysis) and
  ER-BSM-001-diff-changelog-skill (post-approval changelog update).

Story: ER-BSM-001-catalog-editing-skill
Signed-off-by: venu <236371043+Venu-p1@users.noreply.github.com>
… control

Verified write_catalog() (used by every catalog_manager.py command)
has no code-level path-boundary check -- a path-traversal write into
/etc/ succeeds today with no restriction. Per decision, this Story
does not add a guard to that shared function (it's used well beyond
this Story's scope). Instead, edit_catalog.md and bulk_edit_catalog.md
now state explicitly that the write-path boundary (NFR-2,
Req-SEC-I-1/I-4) is an instruction-level control the skill itself must
enforce until a code-level guard exists -- not a guarantee the
underlying tool provides.

Story: ER-BSM-001-catalog-editing-skill
Signed-off-by: venu <236371043+Venu-p1@users.noreply.github.com>
@Venu-p1 Venu-p1 changed the title Feature/ER BSM 001 catalog editing skill 2 feat(catalog_skills): add catalog generation, analysis, editing, and diff/changelog skills Sep 27, 2026
Seven real gaps surfaced by actually exercising the catalog generation,
editing, and diff/changelog skills, fixed together since most touch the
same shared instruction files:

- catalog_generation/SKILL.md: add "Step 4b - Group Package Composition
  Resolution". A.3 only records which groups a role includes, never
  which packages each group actually contains -- only shipped catalog
  JSON has that. When no shipped catalog matched the requested
  stack/arch/os_version, the skill was silently borrowing an unrelated
  stack's catalog (observed: a Slurm catalog request fell back to
  service_k8s_x86_64.json) instead of disclosing the gap. Verified
  against real shipped-catalog data first: most shared groups
  (common_pks, admin_debug_group, ldms_group, ...) have exactly one
  component-set across all 22 shipped catalogs (safe to reuse any
  instance); baseos_group has 3 variants differing only by one
  architecture-specific image_build_<arch> key (closest-match-by-axis
  with disclosure, not a blind pick). No shipped instance at all ->
  refuse and ask, never substitute or fabricate.
- catalog_generation/SKILL.md: add Step 9 (always ask about additional
  packages/custom functional roles) and Step 4a (how to apply that
  answer) -- custom group/role naming validated against A.2's
  layer-naming pattern (verified: all 24 shipped functional layers
  follow <role>_rhel_<os_version>_<architecture> with no exception),
  with baseos_group called out as the one real exception (the group
  name itself never varies by arch/stack/OS version, unlike its layer).
- master_reference/SKILL.md: add a Step 0 to the Selection Catalogue
  gate so a presented menu only ever lists supported options --
  planned/unsupported options no longer appear as noise in the
  interview, only reactively if the operator names one.
- shared/working_directory.md (new): shared scratch-file convention
  (mktemp -d, copy out only after validation, clean up always) used by
  catalog_generation's draft catalog, changelog_generator's default
  diff/changelog outputs, and pre_edit_gate's pre-edit snapshot.
- pre_edit_gate.md: since edit_catalog.md/bulk_edit_catalog.md
  overwrite a catalog in place, take a pre-edit snapshot into the
  working directory *before* applying the edit so
  changelog_generator.md still has a "before" state to diff against
  afterward -- verified end-to-end with a real add + snapshot diff.
- report_renderer.py/catalog_manager.py/changelog_report.html.j2: add
  detect_os_version_cutover() to collapse a whole-catalog OS-version
  re-cut (e.g. 10.0 -> 10.2) into one consolidated summary line instead
  of dozens of near-identical per-package "changed" rows and per-group
  CON-007 warnings that all say the same thing. Verified against the
  real 10.0/10.2 service_k8s_x86_64 sample catalogs: 187 package rows
  collapse to 1 line, 21 duplicate CON-007 warnings collapse to 1
  informational note, with the full old->new layer-name mapping still
  shown; identical-catalog and real-content-change cases are
  unaffected (regression-tested).

Signed-off-by: venu <236371043+Venu-p1@users.noreply.github.com>

This branch has not been deployed

No deployments
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