Skip to content

Govern the solution server hint prompt as a versioned Jinja2 template - #930

Open
fabianvf wants to merge 3 commits into
konveyor:mainfrom
fabianvf:prompt-template-governance
Open

Govern the solution server hint prompt as a versioned Jinja2 template#930
fabianvf wants to merge 3 commits into
konveyor:mainfrom
fabianvf:prompt-template-governance

Conversation

@fabianvf

@fabianvf fabianvf commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

What

Moves the solution server's live hint prompt (generate_hint_v3) out of an inline f-string in server.py and into a versioned Jinja2 template under kai_mcp_solution_server/src/kai_mcp_solution_server/prompts/, rendered through a small render_prompt(...) registry. A checksummed manifest.yaml tracks it.

Why

This is the Kai side of the prompt-template governance we just landed in editor-extensions (ISO 42001 A.5.2). That work explicitly scoped out the solution-server prompts, noting they're owned here — this closes that loop. The hint prompt is effectively the instruction set for hint generation, so it gets version control, peer review, and CI validation independent of the application code. The incident loop now lives in the template; the AST-diff computation stays in Python and is passed in as a variable.

Behavior

No behavior change for the live prompt. A parity suite renders the template and asserts it matches a verbatim copy of the old f-string byte-for-byte across the incident / AST-diff matrix (0/1/N incidents, empty/populated diff, multi-line and special-char fields). Jinja renders None/dicts identically to the old f-strings, so there's no silent drift.

generate_hint_v1 and generate_hint_v2 were never called (only v3 is wired up, at server.py:1098) — they're removed as dead code, along with the now-unused get_diff import.

What's here

  • prompts/ — the Jinja2 template + manifest and the render registry; shipped as package data (verified present in the built wheel).
  • scripts/prompts_version.py + .github/workflows/prompt-validation.yml — validate Jinja syntax, declared-vs-referenced variables, and manifest checksums on any prompts/** change, plus the parity and a deterministic (mock-model) semantic-regression test.
  • PROMPT_GOVERNANCE.md, a new .github/CODEOWNERS (scoped to the prompts dir only), and an audit-evidence doc.

Verification

uv build (template + manifest in the wheel), pytest tests/prompts (7 pass), python scripts/prompts_version.py check, mypy src, and ruff/Trunk all green. requirements.txt regenerated for the new jinja2 dependency.

Needs a repo admin (can't be done in code)

  • Create the @konveyor/kai-prompt-reviewers team.
  • Branch protection requiring the Validate prompt templates check + Code-Owner review on the prompts directory (documented in PROMPT_GOVERNANCE.md).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added governed, structured prompt rendering for migration hints.
    • Introduced a refreshed hint format with consistent sections, numbered guidance, and examples.
  • Bug Fixes

    • Improved validation for missing values, template issues, version mismatches, and content drift.
    • Added automated checks to preserve prompt output consistency.
    • Updated security-related dependency versions to address known vulnerabilities.
  • Documentation

    • Added guidance describing prompt lifecycle, review, validation, and security controls.

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: aa081394-e28f-43c7-bada-e3a3762a5832

📥 Commits

Reviewing files that changed from the base of the PR and between 68e68e4 and 6efdcc7.

⛔ Files ignored due to path filters (1)
  • kai_mcp_solution_server/uv.lock is excluded by !**/*.lock
📒 Files selected for processing (6)
  • .trunk/trunk.yaml
  • kai_mcp_solution_server/pyproject.toml
  • kai_mcp_solution_server/requirements.txt
  • kai_mcp_solution_server/scripts/prompts_version.py
  • kai_mcp_solution_server/src/kai_mcp_solution_server/server.py
  • kai_mcp_solution_server/tests/prompts/test_semantic_regression.py

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

This PR adds prompt governance documentation, a manifest-driven Jinja2 renderer, a generate_hint_v3 template, server integration, validation tooling, regression tests, dependency updates, and Trunk tool updates.

Changes

Prompt governance and rendering

Layer / File(s) Summary
Policy and ownership
.github/CODEOWNERS, kai_mcp_solution_server/PROMPT_GOVERNANCE.md, kai_mcp_solution_server/docs/ISO-42001-A5.2-evidence.md
Ownership, lifecycle, validation, threat-model, evidence, and branch-protection controls are documented for prompt changes.
Manifest and renderer
kai_mcp_solution_server/pyproject.toml, kai_mcp_solution_server/requirements.txt, kai_mcp_solution_server/src/kai_mcp_solution_server/prompts/*
Jinja2 and dependency version constraints are added. The manifest registers generate_hint_v3, and render_prompt loads templates with strict undefined handling.
Template and server
kai_mcp_solution_server/src/kai_mcp_solution_server/prompts/templates/generate_hint_v3.md.jinja, kai_mcp_solution_server/src/kai_mcp_solution_server/server.py
The prompt moves into a Jinja2 template. generate_hint_v3 renders the template, and legacy hint functions and inline prompt construction are removed.
Validation and regression tests
kai_mcp_solution_server/scripts/prompts_version.py, .github/workflows/prompt-validation.yml, kai_mcp_solution_server/tests/prompts/*
The CLI and workflow validate prompt governance rules. Parity and semantic tests validate exact rendering and required prompt content.

Tooling updates

Layer / File(s) Summary
Trunk tool versions
.trunk/trunk.yaml
Trunk plugin, Node.js, Taplo, and markdownlint versions are updated.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: ⚪ Minimal · up to 6efdc

The change is merge-ready after normal checks and review; no actionable merge-blocking risk remains.

Sequence Diagram(s)

sequenceDiagram
  participant Server as server.generate_hint_v3
  participant PromptAPI as render_prompt
  participant Jinja as Jinja2 Environment
  participant Template as generate_hint_v3.md.jinja

  Server->>PromptAPI: Pass incidents and ast_diff_str
  PromptAPI->>Jinja: Resolve generate_hint_v3
  Jinja->>Template: Render template with context
  Template-->>Jinja: Return prompt text
  Jinja-->>PromptAPI: Return rendered prompt
  PromptAPI-->>Server: Return final prompt string
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 15 functions across 6 files. (3 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: moving the solution server hint prompt into a governed, versioned Jinja2 template.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 15 functions across 6 files. (3 skipped: 3 unsupported.)

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@fabianvf
fabianvf force-pushed the prompt-template-governance branch 3 times, most recently from 68e68e4 to e007b11 Compare June 24, 2026 20:55

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
kai_mcp_solution_server/tests/prompts/test_semantic_regression.py (1)

69-73: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert all incident fields that the prompt contract depends on.

The regression currently checks only a subset of incident fields. Add assertions for code_snip, line_number, and variables to catch accidental template regressions in those sections.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@kai_mcp_solution_server/tests/prompts/test_semantic_regression.py` around
lines 69 - 73, The semantic regression test is only validating a subset of the
incident data rendered by the prompt. Update the assertions in
test_semantic_regression to also check code_snip, line_number, and variables for
each incident, alongside the existing uri, message, and violation_name checks,
so the prompt contract covers all fields the template depends on.
.github/workflows/prompt-validation.yml (1)

25-35: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low value

Optional: align with the repo's action-pinning / credential-hygiene policy.

zizmor flags these uses: references as unpinned (not pinned to a commit SHA) and notes actions/checkout doesn't set persist-credentials: false. If the repo enforces a blanket pinning policy, pin to immutable SHAs and disable credential persistence on checkout; otherwise this is consistent with existing workflows and can be deferred.

🔒 Suggested hardening
      - uses: actions/checkout@<commit-sha>  # v4
        with:
          persist-credentials: false
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/prompt-validation.yml around lines 25 - 35, The workflow
step in the prompt-validation job uses unpinned GitHub Actions and checkout
still persists credentials. If this repo follows the pinning/credential-hygiene
policy, update the actions referenced by actions/checkout, actions/setup-python,
and astral-sh/setup-uv in this job to immutable commit SHAs, and set
persist-credentials to false on the actions/checkout step; otherwise leave it
as-is if the repo intentionally allows this pattern.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@kai_mcp_solution_server/PROMPT_GOVERNANCE.md`:
- Around line 75-76: The required status-check name in PROMPT_GOVERNANCE should
match the exact workflow/job label reported by the CI system. Update the status
check entry from Validate prompt templates to the actual check name used by the
prompt validation workflow, and keep the Code Owners requirement unchanged so
the documented branch protection gate aligns with the status shown by the Prompt
Template Validation (ISO 42001 A.5.2) job.

In `@kai_mcp_solution_server/scripts/prompts_version.py`:
- Around line 46-111: `check()` currently validates template integrity but
misses the manifest↔package version contract, so add a version lockstep
validation between `manifest.yaml` and the package version in `pyproject.toml`.
Update `check()` in prompts_version.py to load/compare both versions, report a
clear problem when they differ, and fail the check alongside the existing
`problems` list; use the existing `load_manifest()` flow and extend it with a
helper or inline read of the package version so the CI gate catches drift.

---

Nitpick comments:
In @.github/workflows/prompt-validation.yml:
- Around line 25-35: The workflow step in the prompt-validation job uses
unpinned GitHub Actions and checkout still persists credentials. If this repo
follows the pinning/credential-hygiene policy, update the actions referenced by
actions/checkout, actions/setup-python, and astral-sh/setup-uv in this job to
immutable commit SHAs, and set persist-credentials to false on the
actions/checkout step; otherwise leave it as-is if the repo intentionally allows
this pattern.

In `@kai_mcp_solution_server/tests/prompts/test_semantic_regression.py`:
- Around line 69-73: The semantic regression test is only validating a subset of
the incident data rendered by the prompt. Update the assertions in
test_semantic_regression to also check code_snip, line_number, and variables for
each incident, alongside the existing uri, message, and violation_name checks,
so the prompt contract covers all fields the template depends on.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 58245fea-789e-4024-9729-d5c539b30002

📥 Commits

Reviewing files that changed from the base of the PR and between 29ae739 and 68e68e4.

⛔ Files ignored due to path filters (1)
  • kai_mcp_solution_server/uv.lock is excluded by !**/*.lock
📒 Files selected for processing (16)
  • .github/CODEOWNERS
  • .github/workflows/prompt-validation.yml
  • .trunk/trunk.yaml
  • kai_mcp_solution_server/PROMPT_GOVERNANCE.md
  • kai_mcp_solution_server/docs/ISO-42001-A5.2-evidence.md
  • kai_mcp_solution_server/pyproject.toml
  • kai_mcp_solution_server/requirements.txt
  • kai_mcp_solution_server/scripts/prompts_version.py
  • kai_mcp_solution_server/src/kai_mcp_solution_server/prompts/__init__.py
  • kai_mcp_solution_server/src/kai_mcp_solution_server/prompts/manifest.yaml
  • kai_mcp_solution_server/src/kai_mcp_solution_server/prompts/templates/generate_hint_v3.md.jinja
  • kai_mcp_solution_server/src/kai_mcp_solution_server/server.py
  • kai_mcp_solution_server/tests/prompts/__init__.py
  • kai_mcp_solution_server/tests/prompts/oracle.py
  • kai_mcp_solution_server/tests/prompts/test_parity.py
  • kai_mcp_solution_server/tests/prompts/test_semantic_regression.py

Comment on lines +75 to +76
1. **Require the status check** `Validate prompt templates`.
2. **Require review from Code Owners** so `prompts/**` edits need `@konveyor/kai-prompt-reviewers`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Align required status-check name with the actual workflow/job check.

Line 75 requires Validate prompt templates, but the workflow context is named Prompt Template Validation (ISO 42001 A.5.2). If these don’t match the actual reported check name, branch protection cannot enforce this gate as documented.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@kai_mcp_solution_server/PROMPT_GOVERNANCE.md` around lines 75 - 76, The
required status-check name in PROMPT_GOVERNANCE should match the exact
workflow/job label reported by the CI system. Update the status check entry from
Validate prompt templates to the actual check name used by the prompt validation
workflow, and keep the Code Owners requirement unchanged so the documented
branch protection gate aligns with the status shown by the Prompt Template
Validation (ISO 42001 A.5.2) job.

Comment thread kai_mcp_solution_server/scripts/prompts_version.py
fabianvf and others added 3 commits August 25, 2026 13:27
Extract the live generate_hint_v3 prompt out of server.py into a versioned
Jinja2 asset under src/kai_mcp_solution_server/prompts/, rendered via
render_prompt(). The incident loop now lives in the template; the AST-diff
computation stays in Python and is passed in as a variable. This brings the
solution server's hint prompt under the same governance the editor-extensions
repo adopted for its prompts (ISO 42001 A.5.2) — the surface that work
explicitly left to be governed here.

- prompts/: Jinja2 template + manifest (semver + checksum), render registry;
  ships as package data (verified present in the built wheel)
- byte-exact parity tests prove the template reproduces the previous prompt
  string exactly across the incident / AST-diff matrix, plus a deterministic
  mock-model semantic-regression check
- scripts/prompts_version.py + prompt-validation.yml validate Jinja syntax,
  declared variables, and manifest checksums on any prompts/** change
- PROMPT_GOVERNANCE.md, a new CODEOWNERS, and an audit-evidence doc
- remove the never-called generate_hint_v1/v2 (dead code) and the now-unused
  get_diff import

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Fabian von Feilitzsch <fabian@fabianism.us>
Trunk Check fails on any PR touching Markdown or TOML because two tools can't
run in CI:
  - markdownlint@0.48.0 crashes at startup under the bundled node 18.12.1
    ("SyntaxError: Invalid regular expression flags" — string-width uses the
    unicode-sets `v` regex flag, which needs node 20+).
  - taplo@0.10.0's Linux binary fails to install ("Binary not found") with the
    old plugins definitions.

Bump the node runtime to 22.16.0, the trunk-io/plugins ref to v1.10.2 (refreshes
tool download definitions; pinned tool versions are unchanged), and markdownlint
to 0.49.0. `trunk check` reports no new issues across the changed files.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Fabian von Feilitzsch <fabian@fabianism.us>
From CodeRabbit's review:

- prompts_version.py: the check now fails if the prompt-set version in
  manifest.yaml drifts from the package version in pyproject.toml, enforcing the
  lockstep the governance doc documents.
- test_semantic_regression.py: also assert code_snip, line_number, and variables
  render, so the prompt contract covers every incident field the template
  depends on, not just uri/message/violation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Fabian von Feilitzsch <fabian@fabianism.us>
@fabianvf
fabianvf force-pushed the prompt-template-governance branch from 009c511 to 6efdcc7 Compare August 25, 2026 18:16
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