Skip to content

[DBA-295] Migrate validate-agent-guidance from Bash to Python#79

Open
catstrike wants to merge 1 commit intomainfrom
ls/validate_agent_guidance_py
Open

[DBA-295] Migrate validate-agent-guidance from Bash to Python#79
catstrike wants to merge 1 commit intomainfrom
ls/validate_agent_guidance_py

Conversation

@catstrike
Copy link
Collaborator

Summary

Replaces the Bash validate-agent-guidance script with a typed Python module
that is easier to extend and maintain. Adds MdFile and ClaudeDir
dataclasses for structured, lazy-parsed access to skills and agents.

Changes

Python rewrite of the validator

Replaced scripts/validate-agent-guidance.sh with scripts/validate_agent_guidance.py.
Introduced MdFile (lazy-parsed markdown with cached properties) and
ClaudeDir (.claude/ directory with skill_dirs, skill_files,
agent_files listings). Adds YAML frontmatter validation: name and
description fields required, name must match the skill directory name.

Files
  • scripts/validate_agent_guidance.py
  • scripts/validate-agent-guidance.sh (deleted)

Tooling update

Updated make lint-skills and the pre-commit hook to invoke the Python script.

Files
  • Makefile
  • .pre-commit-config.yaml

Test Plan

  • make lint-skills passes
  • make check passes (ruff + mypy + pre-commit hook)

🤖 Generated with Claude Code

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Migrates the agent guidance/skills Tier-1 validator from a Bash script to a typed Python module, and updates local tooling (Makefile + pre-commit) to invoke the new validator via uv.

Changes:

  • Added scripts/validate_agent_guidance.py implementing skill structure, cross-reference, and eval JSON validation (plus YAML frontmatter checks).
  • Removed scripts/validate-agent-guidance.sh.
  • Updated make lint-skills and the validate-agent-guidance pre-commit hook to run the Python validator.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
scripts/validate_agent_guidance.py New Python implementation of the guidance/skills static validator (structure, references, eval JSON, frontmatter).
scripts/validate-agent-guidance.sh Deleted legacy Bash validator.
Makefile Points lint-skills at the new Python validator.
.pre-commit-config.yaml Updates the local hook to run the new Python validator via uv.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


@cached_property
def _content(self) -> str:
return self.path.read_text()
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Path.read_text() uses the platform default encoding; several SKILL.md files contain non-ASCII characters (e.g., “≥”, “—”), so this can raise decode errors on non-UTF-8 locales. Read files with an explicit encoding="utf-8" (and apply the same to other read_text() calls in this script for consistency).

Suggested change
return self.path.read_text()
return self.path.read_text(encoding="utf-8")
Copilot uses AI. Check for mistakes.
Comment on lines +49 to +59
def frontmatter(self) -> dict[str, str]:
"""Parse YAML-style frontmatter between leading --- delimiters into a flat dict."""
m = re.match(r"^---\n(.*?)\n---\n", self._content, re.DOTALL)
if not m:
return {}
result: dict[str, str] = {}
for line in m.group(1).splitlines():
if ": " in line:
key, _, value = line.partition(": ")
result[key.strip()] = value.strip()
return result
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The frontmatter parsing is a very narrow subset of YAML and is brittle to Windows line endings and common YAML constructs (quoted values containing :, multiline strings, etc.), which can cause false “missing frontmatter”/missing-field errors. Since the repo already depends on PyYAML, consider parsing the frontmatter block with yaml.safe_load and validating it’s a mapping, and loosen the delimiter regex to tolerate \r\n and end-of-file after the closing ---.

Copilot uses AI. Check for mistakes.
Comment on lines +100 to +104
continue

md = MdFile(skill_file)

fm = md.frontmatter
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

validate_skill_structure() creates a new MdFile for each SKILL.md, but the later validators iterate claude.skill_files which creates separate MdFile instances for the same paths. This causes each SKILL.md to be read/parsing work repeated across validators; consider building a single cached list/map of MdFile instances and reusing it across all validations.

Copilot uses AI. Check for mistakes.
uv run python scripts/validate_agent_guidance.py

smoke-skills:
scripts/smoke-test-skills.sh No newline at end of file
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make smoke-skills (scripts/smoke-test-skills.sh) and docs still reference scripts/validate-agent-guidance.sh, which this PR deletes. Update those call sites/docs to invoke uv run python scripts/validate_agent_guidance.py (or make lint-skills) so smoke tests and documentation don’t break after this change.

Suggested change
scripts/smoke-test-skills.sh
$(MAKE) lint-skills
Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants