Metadata-Version: 2.4
Name: sinc-prompt
Version: 1.0.0
Summary: Validator and converter for the sinc-prompt structured LLM prompt format
Author: Mario Alexandre
License: MIT
Project-URL: Homepage, https://tokencalc.pro/spec
Project-URL: Documentation, https://tokencalc.pro/integrations
Project-URL: Repository, https://github.com/mdalexandre/sinc-prompt
Project-URL: Paper, https://doi.org/10.5281/zenodo.19152668
Keywords: sinc,prompt,llm,nyquist,structured-prompting,validation
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# sinc-prompt

Validator and converter for the **sinc-prompt** structured LLM prompt format.

```
x(t) = Sigma x(nT) * sinc((t - nT) / T)
```

sinc-prompt applies Nyquist sampling theory to prompt engineering. A raw prompt is a continuous signal; sinc-prompt samples it at exactly 6 bands -- the minimum rate to reconstruct intent without aliasing (hallucination).

| Band | Weight | Purpose |
|------|--------|---------|
| PERSONA | 7.0% | Who should answer |
| CONTEXT | 6.3% | Situation and facts |
| DATA | 3.8% | Specific inputs |
| CONSTRAINTS | 42.7% | Rules to follow |
| FORMAT | 26.3% | Output structure |
| TASK | 2.8% | The objective |

**Zero dependencies.** Uses only Python stdlib.

## Install

```bash
pip install sinc-prompt
```

## Quick Start

```python
import sinc_prompt

# Validate a sinc-prompt JSON file
is_valid, errors = sinc_prompt.validate("prompt.sinc.json")

# Parse into a dataclass
prompt = sinc_prompt.parse("prompt.sinc.json")
print(prompt.get_band("CONSTRAINTS").x)

# Format into a readable prompt string
text = sinc_prompt.format_prompt(prompt)

# Check Nyquist completeness (0.0 to 1.0)
score = sinc_prompt.nyquist_completeness(prompt)
print(f"Completeness: {score:.1%}")

# Compute signal-to-noise ratio
snr = sinc_prompt.compute_snr(prompt)

# Scatter a raw prompt into 6 bands (no LLM needed)
scattered = sinc_prompt.scatter("You are an expert. Write a sorting function in Python. Use only stdlib.")
print(sinc_prompt.format_prompt(scattered))

# Export back to JSON
data = sinc_prompt.to_json(scattered)
```

## CLI

```bash
# Validate a file
sinc-prompt validate prompt.sinc.json

# Format to readable text
sinc-prompt format prompt.sinc.json

# Show completeness score with per-band breakdown
sinc-prompt completeness prompt.sinc.json

# Scatter a raw prompt into 6 bands
sinc-prompt scatter "Write a Python function that sorts a list"

# Scatter with JSON output
sinc-prompt scatter --json "Write a Python function that sorts a list"
```

## sinc-prompt JSON Format

```json
{
  "formula": "x(t) = Sigma x(nT) * sinc((t - nT) / T)",
  "T": "specification-axis",
  "fragments": [
    {"n": 0, "t": "PERSONA", "x": "You are a senior Python developer."},
    {"n": 1, "t": "CONTEXT", "x": "Django REST API project with PostgreSQL."},
    {"n": 2, "t": "DATA", "x": "Error traceback shows 500 on /api/users/."},
    {"n": 3, "t": "CONSTRAINTS", "x": "Do not modify the database schema. Use only stdlib. Keep backward compatibility. Must pass all existing tests."},
    {"n": 4, "t": "FORMAT", "x": "Return the fix as a unified diff. Include one-sentence root cause."},
    {"n": 5, "t": "TASK", "x": "Fix the 500 error on the users endpoint."}
  ]
}
```

## API Reference

### `validate(sinc_json) -> (bool, list[str])`
Validate a sinc-prompt document. Accepts a dict, JSON string, or file Path. Returns `(is_valid, errors)`.

### `parse(input) -> SincPrompt`
Parse a sinc-prompt from dict, JSON string, or file Path. Returns a `SincPrompt` dataclass. Raises `ValueError` if invalid.

### `format_prompt(sinc) -> str`
Format a sinc-prompt into a `[BAND]\ncontent` string.

### `compute_snr(sinc) -> float`
Signal-to-noise ratio measuring how well band distribution matches ideal weights.

### `nyquist_completeness(sinc) -> float`
Weighted completeness score from 0.0 (empty) to 1.0 (all 6 bands present).

### `scatter(raw_prompt) -> SincPrompt`
Heuristic decomposition of a raw prompt into 6 bands. No LLM required.

### `to_json(sinc) -> dict`
Export a sinc-prompt back to a plain dict in sinc JSON format.

### Types

- **`SincFragment(n, t, x)`** -- A single band fragment.
- **`SincPrompt(formula, T, fragments)`** -- A complete sinc-prompt with helper methods: `get_band()`, `is_complete()`, `band_names()`, `to_dict()`.

### Constants

- **`SINC_BANDS`** -- List of the 6 band names in order.
- **`BAND_IMPORTANCE`** -- Dict mapping band names to their quality weights.
- **`SINC_PROMPT_SCHEMA`** -- JSON Schema (draft-07) as a Python dict.

## Why sinc-prompt?

A raw prompt to an LLM is like a single sample of a continuous signal. By Nyquist's theorem, you need at least 2x the highest frequency component to reconstruct without aliasing. In prompt engineering, "aliasing" manifests as hallucination, off-topic responses, and format violations.

sinc-prompt defines 6 bands as the minimum sampling rate. The weights are empirically derived: CONSTRAINTS at 42.7% dominates because rules are the highest-frequency component of intent -- the most likely to be lost in a raw prompt.

## Links

- [Specification](https://tokencalc.pro/spec)
- [Integrations](https://tokencalc.pro/integrations)
- [Repository](https://github.com/mdalexandre/sinc-prompt)
- [Paper](https://doi.org/10.5281/zenodo.19152668)

## License

MIT
