Spec-Driven Development toolkit for Python
Project description
sddkit
A Python library that makes Spec-Driven Development practical inside Python applications.
sddkit gives authors a typed, validated, programmable representation of an SDD specification and emitters that produce the agent-ingestion artifacts (AGENTS.md, SKILL.md, and a canonical Markdown spec) an AI coding agent can read at session start.
Installation
pip install specddkit
Requires Python 3.10 or later.
Quick Start
from sddkit import (
Spec, Intent, Constraint, AcceptanceCriterion, NonGoal, Dependency,
EngineerRefinement, Unit,
)
spec = Spec(
name="my-service",
identifier="my-service/v1",
version="1.0.0",
status="draft",
intent=Intent(
summary="Provide a reliable widget API.",
details="Serves widget data to downstream consumers with sub-100ms p99 latency.",
),
constraints=[
Constraint(id="C1", text="Must not depend on any proprietary SDK.", kind="must-not"),
],
acceptance_criteria=[
AcceptanceCriterion(
id="AC1",
text="GET /widgets returns 200 with a JSON array.",
input_pattern="GET /widgets with valid auth",
),
],
non_goals=[NonGoal(id="NG1", text="Not a write API in v1.")],
dependencies=[Dependency(name="pydantic", kind="hard")],
)
# Validate operationality (five PM-section components populated)
report = spec.validate_operational()
print(report.is_operational) # True
print(report.issues) # warnings for any missing optional components
# Serialise and round-trip
yaml_text = spec.to_yaml()
spec2 = Spec.from_yaml(yaml_text)
assert spec2 == spec
# Emit agent-ingestion artifacts to disk
with open("AGENTS.md", "w") as f:
f.write(spec.to_agents_md())
with open("SKILL.md", "w") as f:
f.write(spec.emit_skill_file("spec_ingestion"))
# Derive pytest stubs from acceptance criteria and write to disk
for filename, source in spec.derive_tests(framework="pytest").items():
with open(filename, "w") as f:
f.write(source)
Core Concepts
sddkit implements the operational-spec component model from Tickets Don't Compile:
| Component | Class | Required for operationality |
|---|---|---|
| Intent | Intent |
Yes (required field) |
| Constraints | list[Constraint] |
Warning if empty |
| Acceptance Criteria | list[AcceptanceCriterion] |
Yes (error if empty) |
| Non-Goals | list[NonGoal] |
Warning if empty |
| Dependencies | list[Dependency] |
Info if empty |
Serialisation
All three formats round-trip for canonical fields:
spec.to_yaml() # → YAML string; Spec.from_yaml(text) → Spec
spec.to_json() # → JSON string; Spec.from_json(text) → Spec
spec.to_markdown() # → Markdown with YAML front matter; Spec.from_markdown(text) → Spec
Decomposition
from sddkit import EngineerRefinement, Unit
spec_with_refinement = spec.model_copy(update={
"refinement": EngineerRefinement(
decomposition=[
Unit(id="U1", name="Core models", hard_deps=[]),
Unit(id="U2", name="Serialization", hard_deps=["U1"]),
]
)
})
ordered_units = spec_with_refinement.decompose()
# Returns units in topological (dependency-first) order.
# Raises RefinementIncompleteError if a cycle is detected.
Public API
from sddkit import (
Spec,
Intent,
Constraint,
AcceptanceCriterion,
NonGoal,
Dependency,
EngineerRefinement,
Unit,
ValidationReport,
OperationalityError,
RefinementIncompleteError,
SerializationError,
SddkitError,
)
All exceptions inherit from SddkitError.
Development
pip install -e ".[dev]"
pytest # runs tests with coverage
mypy src/sddkit --strict
ruff check src/sddkit
python -m build
twine check dist/*
License
Apache 2.0. See LICENSE.
Project details
Release history Release notifications | RSS feed
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 specddkit-1.0.1.tar.gz.
File metadata
- Download URL: specddkit-1.0.1.tar.gz
- Upload date:
- Size: 22.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7af45afbbc6cdad53530369571235ecf5b4aa31079eb083eb4560582f4d07538
|
|
| MD5 |
4b7ccfba5b0171b2dd131f0cd71f6bdb
|
|
| BLAKE2b-256 |
a276e60af42e6418b55b2ce724e5c2c2a9da0534f20b7df1859b557071a1dae4
|
Provenance
The following attestation bundles were made for specddkit-1.0.1.tar.gz:
Publisher:
publish.yml on gedman4b/sddkit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
specddkit-1.0.1.tar.gz -
Subject digest:
7af45afbbc6cdad53530369571235ecf5b4aa31079eb083eb4560582f4d07538 - Sigstore transparency entry: 1970066825
- Sigstore integration time:
-
Permalink:
gedman4b/sddkit@87fe194d2fe97d2e6c8a0e52f230efad1727272b -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/gedman4b
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@87fe194d2fe97d2e6c8a0e52f230efad1727272b -
Trigger Event:
push
-
Statement type:
File details
Details for the file specddkit-1.0.1-py3-none-any.whl.
File metadata
- Download URL: specddkit-1.0.1-py3-none-any.whl
- Upload date:
- Size: 27.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1e0143ad9124531e15d5efabc93ac89f06f349b3f4260784d7edb4c5d6bf0fb1
|
|
| MD5 |
3bad9d2a6d00a27eddd0f515cae33049
|
|
| BLAKE2b-256 |
5cc4ff8ea863d4ac2cd377a1b6bb4a151ed7da5ea3bc0dc71ef037017911c5ca
|
Provenance
The following attestation bundles were made for specddkit-1.0.1-py3-none-any.whl:
Publisher:
publish.yml on gedman4b/sddkit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
specddkit-1.0.1-py3-none-any.whl -
Subject digest:
1e0143ad9124531e15d5efabc93ac89f06f349b3f4260784d7edb4c5d6bf0fb1 - Sigstore transparency entry: 1970066896
- Sigstore integration time:
-
Permalink:
gedman4b/sddkit@87fe194d2fe97d2e6c8a0e52f230efad1727272b -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/gedman4b
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@87fe194d2fe97d2e6c8a0e52f230efad1727272b -
Trigger Event:
push
-
Statement type: