This release is a pre-release and may not be stable for production use.
Context Compiler Directive Drafter
Turn natural-language requests into candidate Context Compiler directives.
context-compiler-directive-drafter helps hosts translate user requests like:
Please use Docker for container examples.
into candidate directives, such as:
use docker
This package drafts suggestions for the Context Compiler. Only context-compiler applies directives and updates state.
The drafter suggests candidate directives. context-compiler decides what to do with them.
The drafter owns the human-facing acquisition step between messy user input and canonical directive text. That includes deciding when a message is close enough to propose a canonical directive, when the message is not a directive at all, and when the message is too unclear or malformed to safely interpret without more help. It does not become an authority over state, permissions, or application.
When To Use It
Use this package when you want to:
- Translate user requests into safe, canonical directives.
- Handle near-canonical input, alternate phrasing, and malformed-but-recoverable directive attempts before compiler handoff.
- Distinguish "no directive" from "unknown or failed interpretation" in a stable host-facing contract.
- Avoid accidental or unsafe state changes from ambiguous input.
- Add a conservative natural-language-to-directive step before applying changes.
This package owns the human-facing acquisition boundary, including when to propose a canonical directive, when to abstain, and when to ask for clarification or interpretation confirmation before compiler handoff.
The normative acquisition contract lives in docs/DrafterAcquisitionSpec.md. This package does not own:
- authoritative compiler state
- the decision about whether a canonical directive is allowed in the current context
- directive application or state mutation
- invention of new directive semantics beyond the compiler-owned contract
Installation
Install in your host environment:
pip install "context-compiler-directive-drafter"
For local development:
uv sync --group dev
Basic Usage
Draft a candidate directive:
from context_compiler_directive_drafter import DirectiveDrafter
from context_compiler_directive_drafter import NoDirective, UnknownDirective
drafter = DirectiveDrafter()
result = drafter.draft_directive(
"Please use Docker for container examples.",
)
if hasattr(result.result, "text"):
print("Candidate directive:", result.result.text)
elif isinstance(result.result, NoDirective):
print("No canonical directive drafted:", result.result.reason)
elif isinstance(result.result, UnknownDirective):
print("Need clarification before drafting:", result.result.reason)
The host validates drafted output before passing it to engine.step(...).
For small runnable examples, see examples/basic_usage.py and examples/prompt_rendering.py.
Public API
Public interface:
DirectiveDrafter(): Synchronous orchestration over heuristic preprocessing, optional fallback acquisition, fallback output parsing and validation, and final result construction.DraftResult: Structured non-authoritative result returned byDirectiveDrafter.draft_directive(...).NoDirectiveandUnknownDirective: Non-canonical drafting result variants with preserved reasons.preprocess_heuristic(message): Heuristically draft a candidate directive.parse_preprocessor_output(raw_output): Validate and parse drafting output.validate_preprocessor_output(raw_output): Classify raw output as directive, no_directive, or unknown.get_converter_prompt(): Load the shared static converter system prompt.- Constants and sentinels exported from the package.
Output Contract
The intended drafting boundary is:
- input: user text
- output:
DraftResult(source=<final producer>, result=<drafting-layer variant>)
Every drafting path should end in one of three host-visible result variants:
CanonicalDirective: a proposed canonical directive that is ready for compiler review and independent policy checksNoDirective(reason=...): the input is not asking for a directiveUnknownDirective(reason=...): the input appears directive-related or interpretation failed, but the drafter should not guess
The source field records only the final producer of the returned drafting
result, such as heuristic or the source metadata configured for a
host-provided fallback acquisition callback.
It does not track fallback history.
A returned CanonicalDirective means "this is a proposed canonical directive,"
not "this directive is permitted" and not "this directive has been applied."
Recommended Host Flow
- Run
DirectiveDrafter().draft_directive(message)as the high-level drafting API. It always tries heuristic drafting first and may optionally call a non-authoritative fallback acquisition callback when the heuristic result is not directly returnable. - If you configure a fallback, have it return canonical directive text or
None, and register the source metadata you want preserved on any fallback-producedDraftResult. - If the result yields a
CanonicalDirective, pass that canonical directive tocontext-compilerfor authoritative review and application. - If the result yields
NoDirective, continue the host flow without a directive handoff. - If the result yields
UnknownDirective, preserve the boundary: ask for clarification, show resubmission guidance, or retry drafting in a safer workflow.
The public helpers remain available unchanged for hosts that prefer to orchestrate preprocessing and validation themselves.
Safety Guidance:
- Always validate drafting output before compiler handoff.
- Never pass raw model output directly to the compiler.
- Bypass drafting when clarification is pending.
- Do not drive authoritative transitions from package-owned drafting code.
- Do not read or mutate
engine.statedirectly from package-owned drafting code. - Prefer abstaining over unsafe guesses.
- Output validation checks the canonical directive contract, not whether the directive is allowed in context.
- A structurally valid drafted directive may still be the wrong interpretation of the user's meaning.
- Reviewed semantic drafting belongs in a separate higher-level workflow such as preview, approval, or engine application.
Hosts may use UnknownDirective to trigger clarification, confirmation, or
resubmission guidance. That interaction is part of the human-input drafting
boundary, but any eventual canonical directive must still be revalidated before
compiler handoff.
Do not pass raw model output to the compiler.
Prompt Resources
The package includes one shared static converter system prompt for integrations that use model-based drafting when heuristic drafting does not produce a result.
Use get_converter_prompt() to load the canonical shared converter system prompt.
The converter prompt is guidance only:
- it teaches the basic directive grammar and drafting boundary
- it does not inject premise, policy, engine, or user-specific runtime state
- it does not approve or apply directives
- it does not replace package parsing or validation
- its
<NO_DIRECTIVE>token is part of the LLM/provider prompt protocol, not aDraftResultvariant and not a Context Compiler grammar rule
If you wire that model call into DirectiveDrafter, reuse the shared
converter prompt, configure the fallback callback with source metadata, and
return only candidate directive text or None. DirectiveDrafter performs
parsing, validation, normalization, and DraftResult construction itself.
Any model output should still be validated with
parse_preprocessor_output(...) or validate_preprocessor_output(...) before
it is shown or used.
Current Limits
This package is intentionally conservative. It abstains or returns unknown
when input is:
- Ambiguous, mixed-intent, or quoted.
- Embedded in prose, markdown, or code.
- Not safely interpretable as one canonical directive.
Boundary rules:
- Process the full message, not fragments.
- Emit at most one canonical directive.
- Abstain when one message contains multiple directive-shaped instructions.
- Do not mine surrounding prose for commands.
- Do not split one message into multiple drafted directives.
- Do not invent new directive semantics.
- Avoid broad semantic rewrites that effectively create new policy meaning.
- Prefer false negatives over false positives.
context-compiler-directive-drafter only proposes at most one candidate
directive. context-compiler remains responsible for independently enforcing
the single-directive invariant before any authoritative application.
The drafter should consume the compiler-owned grammar contract once that extracted contract is available. This package should not duplicate or become the normative owner of grammar rules in its own documentation or prompt resources.
Hosts that want broader proposal behavior should implement it explicitly.
CLI
The CLI command is directive-drafter. The CLI currently supports a limited set of behaviors:
uv run directive-drafter "please make replies concise"
It returns a non-zero exit status because the public high-level drafting API requires a host-provided engine context.
Development
Run local checks:
uv run pre-commit run --all-files
uv run pytest
License
Apache-2.0
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file context_compiler_directive_drafter-0.2.0.dev1.tar.gz.
File metadata
- Download URL: context_compiler_directive_drafter-0.2.0.dev1.tar.gz
- Upload date:
- Size: 85.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cae1bd43e145e96d895178154c0c261b8ed28037b38d5232f4b00ee57ae88e4f
|
|
| MD5 |
d5672c6c7d4143acd4d64367e324462f
|
|
| BLAKE2b-256 |
6bb1990d8ea99be4386ca6be2633446a904fdc759269c45e45079c9ba0f0c06c
|
Provenance
The following attestation bundles were made for context_compiler_directive_drafter-0.2.0.dev1.tar.gz:
Publisher:
publish-pypi.yml on rlippmann/context-compiler-directive-drafter
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
context_compiler_directive_drafter-0.2.0.dev1.tar.gz -
Subject digest:
cae1bd43e145e96d895178154c0c261b8ed28037b38d5232f4b00ee57ae88e4f - Sigstore transparency entry: 2403470036
- Sigstore integration time:
-
Permalink:
rlippmann/context-compiler-directive-drafter@5428bb9ac68017ee562d496bdca7498aa0782fab -
Branch / Tag:
refs/tags/v0.2.0dev1 - Owner: https://github.com/rlippmann
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@5428bb9ac68017ee562d496bdca7498aa0782fab -
Trigger Event:
release
-
Statement type:
File details
Details for the file context_compiler_directive_drafter-0.2.0.dev1-py3-none-any.whl.
File metadata
- Download URL: context_compiler_directive_drafter-0.2.0.dev1-py3-none-any.whl
- Upload date:
- Size: 18.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
16b294e8ab63e08fc6e494dfa7777bea62c2f1db9b19473f4a656968b9848ca6
|
|
| MD5 |
46cc3916f2f27e6f6e0e7aaff24c63c9
|
|
| BLAKE2b-256 |
34b6b2982194d61a7a9affbc2afefa2d36eb1d1c49918664c9c1fad6c366ea31
|
Provenance
The following attestation bundles were made for context_compiler_directive_drafter-0.2.0.dev1-py3-none-any.whl:
Publisher:
publish-pypi.yml on rlippmann/context-compiler-directive-drafter
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
context_compiler_directive_drafter-0.2.0.dev1-py3-none-any.whl -
Subject digest:
16b294e8ab63e08fc6e494dfa7777bea62c2f1db9b19473f4a656968b9848ca6 - Sigstore transparency entry: 2403470396
- Sigstore integration time:
-
Permalink:
rlippmann/context-compiler-directive-drafter@5428bb9ac68017ee562d496bdca7498aa0782fab -
Branch / Tag:
refs/tags/v0.2.0dev1 - Owner: https://github.com/rlippmann
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@5428bb9ac68017ee562d496bdca7498aa0782fab -
Trigger Event:
release
-
Statement type: