Metadata-Version: 2.5
Name: prompt-crafter
Version: 1.0.1
Summary: Say what the picture must contain, check that it does, and refuse when it does not. A typed contract of depictable claims drives both the prompt and the gate that verifies the pixels.
Project-URL: Homepage, https://mcp-tool-shop-org.github.io/prompt-craft/
Project-URL: Documentation, https://mcp-tool-shop-org.github.io/prompt-craft/handbook/
Project-URL: Repository, https://github.com/mcp-tool-shop-org/prompt-craft
Project-URL: Changelog, https://github.com/mcp-tool-shop-org/prompt-craft/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/mcp-tool-shop-org/prompt-craft/issues
Author-email: mcp-tool-shop <64996768+mcp-tool-shop@users.noreply.github.com>
License: MIT License
        
        Copyright (c) 2026 mcp-tool-shop
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: contract,diffusion,dspy,generative-assets,sprite,verifier
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Multimedia :: Graphics
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: Software Development :: Testing
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: pydantic<3,>=2.6
Requires-Dist: typer<0.28,>=0.12
Provides-Extra: dev
Requires-Dist: mypy<3,>=1.11; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff<0.17,>=0.6; extra == 'dev'
Provides-Extra: image
Requires-Dist: accelerate>=0.33; extra == 'image'
Requires-Dist: diffusers>=0.30; extra == 'image'
Requires-Dist: numpy>=1.26; extra == 'image'
Requires-Dist: pillow<14,>=10.0; extra == 'image'
Requires-Dist: torch>=2.4; extra == 'image'
Requires-Dist: transformers>=4.44; extra == 'image'
Provides-Extra: synth
Requires-Dist: dspy-ai>=2.5; extra == 'synth'
Requires-Dist: httpx>=0.27; extra == 'synth'
Description-Content-Type: text/markdown

# prompt-crafter

**Say what the picture must contain. Check that it does. Refuse when it doesn't.**

A generative image pipeline will happily hand you a hero with the wrong face, the wrong palette
and none of the faction's markings — and report success, because nothing looked. prompt-crafter
replaces the opaque prose prompt with a **typed contract of depictable claims**, uses that same
list twice — once to write the prompt, once to check the pixels — and **blocks the asset when a
required claim is not there**.

**The one idea:** the contract's atom list is *the same list used twice.* Writing the prompt and
checking the result read from one source, so the thing you asked for is the thing that gets
verified. That is what closes the loop an opaque prompt leaves open.

## Install

```bash
pip install prompt-crafter
pcraft --help
```

The distribution is `prompt-crafter`; the import package and the command are `pcraft`. Requires
Python 3.11+. CI runs 3.11 and 3.13 on the core + `[dev]`. The `[image]` extra
is not claimed on 3.11. The core's only runtime dependency is `pydantic`.

Model tiers are bring-your-own: the model-tier verifiers need `t2v-metrics` (PyPI) and
`ai-eyes-mcp` (a separate mcp-tool-shop package), which **no extra declares** — no version
has been integration-tested against this build, and pinning one would claim a compatibility
nobody measured. `pcraft doctor` reports both under "model tier". The deterministic palette
verifier needs neither — it reads PNGs with the stdlib, no Pillow required.

```bash
pcraft demo              # the whole loop end-to-end, no GPU, deterministic stubs
pcraft list              # contract ids in the store
pcraft validate          # resolve + compile the question DAG, no generate
pcraft gate <image>      # check an image against a contract
pcraft recipe            # emit the Cloud Kontext + fist-only Fill graph
pcraft replay <record>   # re-read a bound asset's provenance receipt
```

## What a contract looks like

Not a prose prompt. A list of **atomic, depictable, individually checkable** claims:

- **`must_have`** — a garment, a palette, a silhouette, a sigil. Each names which gate tier
  verifies it, a severity, and optionally a `depends_on` edge, so there is no point verifying the
  colour of an axe that is not there.
- **`must_not`** — anti-constraints, verified as **absence on the pixels**. Not a negative prompt:
  negative prompts leave residual features and fall to paraphrase.
- **`identity_ref`** — a reference plate. **Identity is conditioning, not tokens.** Anatomical
  text makes a diffusion model render a specimen; a reference image binds the specific face.

Contracts inherit — a character extends a faction — and inheritance is **fail-closed**: a child
may raise a requirement, never relax or silently drop one it inherited.

## The exit code is the point

| exit | meaning |
|---|---|
| `0` | the gate ran and every required atom passed |
| `1` | bad arguments or a malformed contract |
| `2` | it ran, and a required atom **failed** |
| `3` | it ran, and the result is **unconfirmed** — the human band |
| `4` | it **could not run** |

The `2` / `4` split is the whole design. **"I could not check" and "I checked and it is bad" are
different facts.** Merging them is why browsers soft-fail certificate revocation, and why
monitoring standards have carried a distinct *unknown* verdict since the 1990s. Every gate
transcript also reports how many required tiers actually executed, so a gate that quietly stopped
checking cannot read as a pass.

The verifier is always a **different model family from the generator**, enforced by a guard that
refuses to run otherwise. CLIPScore is not used as the gate metric — it behaves as a bag of
concepts, blind to which attribute belongs to which object.

## Honest status

**v1.0.0 — the INTERFACES are stable. The pictures are not finished, and this document does not pretend otherwise.**

A `1.0.0` here is a claim about the CLI, the import paths, the exit codes and the two on-disk
formats — enumerated in STABILITY.md, along with what is deliberately excluded.
It is not a claim that the plate lands in the pixels. The gaps below are real and they get
better in minor releases; what stops moving is the surface you build against.

- **338 tests passing** (counted 2026-08-18), GPU-free and deterministic. The whole suite runs
  against a mock generator and verifier, which is what proves the plugin boundary holds.
- Flux Fill inpaint is wired. `method=reference` writes the Cloud recipe (`GATE_CLOUD_SUBMIT`).
  ControlNet pose and IP-Adapter stay refused on Flux.
- The eleven compound decision points in the core are **mutation-tested** — 20 of 21 mutants
  killed, and the survivor is named rather than hidden.
- SDXL ControlNet OpenPose, IP-Adapter, LoRA, **InstantID**, and regional inpaint are
  **wired and covered by fake-torch tests**. InstantID and IP-Adapter cannot share one
  generate. Two IP-Adapter plates stay on one adapter (all images; scale is the
  strongest lock). Local `generate()` **ran** on the 5090 (2026-08-18, seed
  `169405236028824`). The frame is orcish; grip, sigil, and bracer did not land.
  Flux refuses those identity methods.
- `pcraft recipe` emits the Cloud Kontext stitch + left crop + fist-only Fill graph. A live
  Cloud submit (2026-08-18) produced a single-panel crop and kept the bracer.
- Tier-2 is a real DSG expansion. Escalation is a contrastive checkpoint. A live GEPA
  compile ran 2026-08-18 on local Ollama `hermes3:8b` (600B was not up). Pinned
  `sprite.synth.v1-gepa.json`. The seed artifact is untouched. The per-asset loop
  still uses `TemplateSynthesizer`.
- The identity sub-gate is **not wired**. Its thresholds have no holdout.
- v1.0.0 is a claim about interfaces, not pictures. The CLI commands, the exit-code
  contract, the listed import paths, and both on-disk formats are semver-covered --
  `STABILITY.md` in the repo names each one, and names what is excluded. The capability
  gaps above stay disclosed and close in minor releases.

## Trust

No credentials are read, stored or transmitted. **No telemetry** — there is no opt-out because
there is nothing to opt out of. The core imports no networking library at all; the optional
extras reach a model host by their nature, and installing them is a choice. File operations are
**not sandboxed**: `--records-dir` and `--db` write where you point them, deliberately, for a
local-first tool.

Deliberate refusals carry a code, a message and a hint, and **raise rather than `assert`** — so
`-O` cannot delete them, and the suite runs a second time under `-O` to prove it.

---

**[Documentation and handbook →](https://mcp-tool-shop-org.github.io/prompt-craft/)**
· [Source](https://github.com/mcp-tool-shop-org/prompt-craft)
· [Changelog](https://github.com/mcp-tool-shop-org/prompt-craft/blob/main/CHANGELOG.md)

MIT
