Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .specsmith/requirements.json
Original file line number Diff line number Diff line change
Expand Up @@ -3560,12 +3560,13 @@
"id": "REQ-366",
"version": 1,
"title": "Activating the chronomemory ChronoStore ESDB backend requires a valid commercial license key",
"description": "When chronomemory is installed, specsmith must verify the presence and cryptographic validity of an Ed25519-signed license file before activating ChronoStore (ChronoMemory backend engine). The license file location is resolved from SPECSMITH_ESDB_KEY environment variable or ~/.specsmith/esdb.key. If the key is absent or invalid the backend silently falls back to SqliteStore with a one-time warning. The SPECSMITH_ESDB_BACKEND=sqlite environment variable force-selects SQLite regardless of key presence.",
"description": "When chronomemory is installed, specsmith must verify the presence and cryptographic validity of an Ed25519-signed license file before activating ChronoStore (ChronoMemory backend engine). The license file location is resolved from SPECSMITH_ESDB_KEY environment variable or ~/.specsmith/esdb.key. If the key is absent or invalid the backend silently falls back to SqliteStore with a one-time warning. The SPECSMITH_ESDB_BACKEND=sqlite environment variable force-selects SQLite regardless of key presence. The base specsmith package must include the cryptography verifier required by `specsmith esdb enable`, so clean pip and pipx installations can activate a valid license without a separate dependency injection.",
"source": "commercial licensing model",
"status": "accepted",
"test_ids": [
"TEST-367",
"TEST-372"
"TEST-372",
"TEST-472"
]
},
{
Expand Down
12 changes: 12 additions & 0 deletions .specsmith/testcases.json
Original file line number Diff line number Diff line change
Expand Up @@ -5110,5 +5110,17 @@
"input": {},
"expected_behavior": {},
"confidence": 1.0
},
{
"id": "TEST-472",
"version": 1,
"title": "Base package metadata includes cryptography for ESDB license activation",
"description": "Verify pyproject.toml lists cryptography in base project dependencies, so a clean pipx install can execute specsmith esdb enable without a manual pipx inject.",
"requirement_id": "REQ-366",
"type": "unit",
"verification_method": "pytest tests/test_esdb_license.py::test_base_install_includes_cryptography_for_license_verification",
"input": {},
"expected_behavior": {},
"confidence": 1.0
}
]
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ consolidated into the next published release.

## [Unreleased]

## [0.22.1] - 2026-07-13
### Fixed
- **ESDB license activation in pipx** (#295) - The Ed25519 `cryptography` verifier
is now a base SpecSmith dependency, so `specsmith esdb enable` works in a clean
`pipx install specsmith` environment without a manual `pipx inject` workaround.

## [0.22.0] - 2026-07-10
### Added
- CPU fallback for local model detection (REQ-445) - When no GPU is detected,
Expand Down Expand Up @@ -922,7 +928,8 @@ See git history for per-commit details on intermediate versions.

---

[Unreleased]: https://github.com/layer1labs/specsmith/compare/v0.22.0...HEAD
[Unreleased]: https://github.com/layer1labs/specsmith/compare/v0.22.1...HEAD
[0.22.1]: https://github.com/layer1labs/specsmith/compare/v0.22.0...v0.22.1
[0.22.0]: https://github.com/layer1labs/specsmith/compare/v0.20.1...v0.22.0
[0.20.1]: https://github.com/layer1labs/specsmith/compare/v0.20.0...v0.20.1
[0.20.0]: https://github.com/layer1labs/specsmith/compare/v0.19.2...v0.20.0
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ If you hold a chronomemory ESDB license, activate the commercial backend:
pip install "specsmith[esdb]" # installs chronomemory from PyPI
# or if using pipx:
pipx inject specsmith "chronomemory>=0.2.0" # inject into the specsmith pipx venv
# The license verifier is included in base specsmith; no cryptography injection is needed.

# Step 2 — activate your license key
specsmith esdb enable --key-file /path/to/your.esdb.key
Expand Down
18 changes: 10 additions & 8 deletions docs/COMPLIANCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
- **Type**: python
- **Language**: python
- **VCS Platform**: github
- **Spec Version**: 0.22.0
- **Spec Version**: 0.22.1

## Verification Tools

Expand All @@ -21,10 +21,10 @@

## Audit Summary

- **Passed**: 73
- **Failed**: 0
- **Passed**: 74
- **Failed**: 1
- **Fixable**: 0
- **Status**: Healthy
- **Status**: Issues found

- ✓ Required file AGENTS.md exists
- ✓ Required file LEDGER.md exists
Expand All @@ -50,7 +50,7 @@
- ✓ session-protocol.yaml valid (m001 content-blob, kind=session-protocol)
- ✓ verification.yaml valid (m001 content-blob, kind=verification)
- ✓ All 412 accepted REQ(s) have test coverage
- ✓ LEDGER.md has 467 lines (within 500 threshold)
- ✓ LEDGER.md has 475 lines (within 500 threshold)
- ✓ 0 open, 0 closed TODOs
- ✓ AGENTS.md: 122 lines
- ✓ docs/governance/RULES.md: 18 lines
Expand Down Expand Up @@ -99,9 +99,13 @@
- ✓ WI-DA14F483 risk=medium gates satisfied
- ✓ WI-8F467602 risk=medium gates satisfied
- ✓ WI-5C560143 risk=medium gates satisfied
- ✗ WI-6C92EE21 risk=medium missing gates: linked tests
- ✓ WI-260B314F risk=low gates satisfied

## Recent Activity

- `bf45813 Merge pull request #294 from layer1labs/codex/close-release-0.22.0`
- `0f75440 chore(governance): close v0.22.0 release`
- `61b556e Merge pull request #293 from layer1labs/codex/release-0.22.0`
- `1f75e19 release: prepare v0.22.0`
- `52c33fd KILL SWITCH ACTIVATED: emergency stop`
Expand All @@ -110,11 +114,9 @@
- `05d3e38 fix: clear remaining post-merge CodeQL findings`
- `eafcd63 Merge pull request #291 from layer1labs/codex/epistemic-release`
- `76adac6 fix: resolve remaining CodeQL review findings`
- `cf91bab merge: integrate Zoo/Roo governance configuration`
- `ec2e978 wi_close WI-094C4FE3: Published archive/feat-zoo-roo-mcp-integration-202`

**Contributors:**
- 725 Tristen Pierson
- 726 Tristen Pierson
- 5 dependabot[bot]
- 1 Aqil Aziz

Expand Down
14 changes: 14 additions & 0 deletions docs/LEDGER.md
Original file line number Diff line number Diff line change
Expand Up @@ -465,3 +465,17 @@
- **Type**: wi_close
- **Status**: complete
- **Chain hash**: `f3bbad392d19900e...`

## 2026-07-13T18:08 — KILL SWITCH ACTIVATED: emergency stop
- **Author**: specsmith-operator
- **Type**: kill-switch
- **REQs affected**: REG-005
- **Status**: complete
- **Epistemic status**: high
- **Chain hash**: `46ed7529d803de9b...`

## 2026-07-13T18:35 — wi_archive WI-6C92EE21: Superseded by WI-260B314F, which implements issue #295 under REQ-366 with TEST-472 coverage.
- **Author**: specsmith
- **Type**: wi_archive
- **Status**: complete
- **Chain hash**: `f43dc947dfb44117...`
2 changes: 1 addition & 1 deletion docs/SPECSMITH.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ description: |
through governance, traceability, and automated compliance checking.

type: python
version: 0.22.0
version: 0.22.1
license: MIT
author: Layer1 Labs
url: https://github.com/layer1labs/specsmith
Expand Down
4 changes: 3 additions & 1 deletion docs/requirements/yaml_governance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,9 @@
from SPECSMITH_ESDB_KEY environment variable or ~/.specsmith/esdb.key. If the
key is absent or invalid the backend silently falls back to SqliteStore with a
one-time warning. The SPECSMITH_ESDB_BACKEND=sqlite environment variable force-selects
SQLite regardless of key presence.
SQLite regardless of key presence. The base specsmith package must include the
cryptography verifier required by `specsmith esdb enable`, so clean pip and pipx
installations can activate a valid license without a separate dependency injection.
source: commercial licensing model
- id: REQ-367
title: chronomemory must carry a proprietary commercial license separate from specsmith
Expand Down
4 changes: 4 additions & 0 deletions docs/site/esdb.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,10 @@ specsmith esdb enable --key-file /path/to/your-org.esdb.key
The key is copied to `~/.specsmith/esdb.key`. Every subsequent specsmith command
automatically uses ChronoStore as long as the key is present and valid.

The Ed25519 verifier used by `specsmith esdb enable` is included with the base
specsmith package, including `pipx` installs. Only the commercial `chronomemory`
backend needs the extra `pipx inject` step above.

**Step 3 — verify ChronoStore is active**

```bash
Expand Down
6 changes: 6 additions & 0 deletions docs/site/esdb/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ Terms: [COMMERCIAL-LICENSE.md (ChronoMemory only)](https://github.com/layer1labs
If you use specsmith, the simplest path is `pip install "specsmith[esdb]"`.
See the [ESDB overview](../esdb.md#licensing) for the full two-tier licensing summary.

The base specsmith package includes the Ed25519 license verifier, including in a
`pipx` installation. Only the commercial ChronoMemory backend needs an additional
package install.

---

## Requirements
Expand All @@ -39,6 +43,8 @@ specsmith esdb enable --key-file /path/to/your.esdb.key
specsmith esdb status # confirms ChronoMemory / ChronoStore backend is active
```

No `pipx inject specsmith cryptography` step is required before activating a license.

## Install standalone (without specsmith)

```bash
Expand Down
4 changes: 2 additions & 2 deletions docs/tests/overflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -648,5 +648,5 @@
type: integration
verification_method: pytest tests/test_esdb_enforcement.py -k save_does_not_commit
description: Verify save normalizes the Git policy, commits no SQLite cache, migration
backup, marker, state, or agent migration artifact, and retains the mergeable session
event log as canonical source of truth.
backup, marker, state, or agent migration artifact, and retains the mergeable
session event log as canonical source of truth.
8 changes: 8 additions & 0 deletions docs/tests/yaml_governance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1184,3 +1184,11 @@
input: {}
expected_behavior: {}
confidence: 1.0
- id: TEST-472
title: Base package metadata includes cryptography for ESDB license activation
requirement_id: REQ-366
type: unit
verification_method: pytest tests/test_esdb_license.py::test_base_install_includes_cryptography_for_license_verification
description: Verify pyproject.toml lists cryptography in base project dependencies,
so a clean pipx install can execute specsmith esdb enable without a manual pipx
inject.
10 changes: 5 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "specsmith"
version = "0.22.0"
version = "0.22.1"
description = "AEE governance toolkit for AI-assisted development — session preflight gates, multi-agent dispatch, requirements↔test traceability, ESDB persistence, MCP server, and skills for Warp, Cursor, Claude Code, Copilot, Windsurf, and Aider."
readme = "README.md"
license = "MIT"
Expand Down Expand Up @@ -37,6 +37,8 @@ classifiers = [

dependencies = [
"click>=8.1",
# `specsmith esdb enable` verifies Ed25519 license signatures in every install.
"cryptography>=42.0",
"jinja2>=3.1",
"pyyaml>=6.0",
"pydantic>=2.0",
Expand All @@ -54,15 +56,13 @@ dev = [
"mypy>=1.10",
"pre-commit>=3.0",
"types-pyyaml>=6.0",
"cryptography>=42.0", # needed for test_esdb_license.py signing helpers
]
# ESDB commercial backend — requires a valid license from licensing@layer1labs.ai
# Install: pip install specsmith[esdb]
# Activate: specsmith esdb enable --key-file /path/to/your.esdb.key
# Terms: https://github.com/layer1labs/specsmith/blob/develop/COMMERCIAL-LICENSE.md
esdb = [
"chronomemory>=0.2.7", # proprietary commercial — ChronoMemory terms only (not SQLite free tier)
"cryptography>=42.0",
]
docs = [
"mkdocs>=1.6",
Expand Down Expand Up @@ -95,8 +95,8 @@ all = [
"ruff>=0.4",
"mypy>=1.10",
]
# cryptography for license verification (usable without full esdb extra)
license-verify = ["cryptography>=42.0"]
# Compatibility extra: cryptography is now part of every supported installation.
license-verify = []

[project.scripts]
specsmith = "specsmith.cli:main"
Expand Down
2 changes: 1 addition & 1 deletion src/specsmith/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@
try:
__version__: str = _pkg_version("specsmith")
except PackageNotFoundError: # running from source without install
__version__ = "0.22.0" # fallback: keep in sync with pyproject.toml
__version__ = "0.22.1" # fallback: keep in sync with pyproject.toml
2 changes: 1 addition & 1 deletion src/specsmith/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -3853,7 +3853,7 @@ def channel_set_cmd(channel: str) -> None:
if channel == "stable" and is_prerelease_version(__version__):
raise click.UsageError(
"Cannot select stable while a prerelease is installed. "
f"Install a stable build first: {version_mismatch_remediation('0.22.0')}"
f"Install a stable build first: {version_mismatch_remediation('0.22.1')}"
)

set_persisted_channel(channel)
Expand Down
2 changes: 1 addition & 1 deletion src/specsmith/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ class ProjectConfig(BaseModel):
),
)
language: str = Field(default="python", description="Primary language/runtime")
spec_version: str = Field(default="0.22.0", description="Spec version to scaffold from")
spec_version: str = Field(default="0.22.1", description="Spec version to scaffold from")
description: str = Field(default="", description="Short project description")

# Options
Expand Down
12 changes: 12 additions & 0 deletions tests/test_esdb_license.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,18 @@ def _make_license_file(
# ---------------------------------------------------------------------------


def test_base_install_includes_cryptography_for_license_verification() -> None:
"""TEST-472: pipx base installs need the verifier used by esdb enable."""
pyproject = Path(__file__).resolve().parents[1] / "pyproject.toml"
base_dependencies = pyproject.read_text(encoding="utf-8").split(
"[project.optional-dependencies]", maxsplit=1
)[0]

assert any(
line.strip().startswith('"cryptography>=42.0"') for line in base_dependencies.splitlines()
)


def test_valid_license(tmp_path: Path) -> None:
key = _make_license_file(tmp_path)
status = verify_license_file(key)
Expand Down
Loading