Metadata-Version: 2.4
Name: guardspine-prompts
Version: 0.1.0
Summary: Render governance rubrics into reviewer-model prompts (GuardSpine)
Author: GuardSpine Team
License-Expression: BUSL-1.1
Keywords: code-review,governance,guardspine,prompt,rubric
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: Other/Proprietary License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# guardspine-prompts

Renders governance rubrics into the prompt given to reviewer models.

A rubric is guidance for the models — what to look for once the risk tier has
decided they should look at all. This package turns a rubric into the block
that carries each rule's id, severity and intent, so a model finding can cite
the control it hit.

It exists as a package because it had two implementations: one in the
GuardSpine monorepo and a vendored copy in `codeguard-action`, which cannot
import the monorepo. They were held in step by a golden vector checked into
both repos — which an audit correctly called theatre, since each repo compared
its own renderer against its own copy and no CI ever compared the two. A
private copy of shared logic is what produced the v2.2.0 signature failure.

## Sanitisation, honestly

Free-text rubric fields have angle brackets stripped and whitespace collapsed.
Identifier fields (`id`, `severity`) are allowlisted, because they are cited
verbatim in findings.

That is **display integrity, not prompt-injection resistance**. A fluent
directive needs no tags. What prevents a hostile rubric steering a review is
that the party under review cannot choose the rubric — see the base-ref trust
boundary in `codeguard-action`.

## Use

```python
from guardspine_prompts import format_rubric_context

block = format_rubric_context([{"name": "SOX ITGC", "version": "1.2", "rules": [...]}])
```

Returns `""` when no rubric is active, so prompts stay byte-identical for
callers with nothing selected.
