Metadata-Version: 2.4
Name: cdd-cmdb-spec
Version: 1.0.0
Summary: Test suite specification for a compliant CMDB instance
Author: CDD-CMDB Contributors
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/syndicalt/cdd-cmdb
Project-URL: Repository, https://github.com/syndicalt/cdd-cmdb
Project-URL: Documentation, https://syndicalt.github.io/cdd-cmdb/
Project-URL: Issues, https://github.com/syndicalt/cdd-cmdb/issues
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: Pytest
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
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 :: Testing
Classifier: Topic :: System :: Systems Administration
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.27
Requires-Dist: pytest>=8
Requires-Dist: hypothesis>=6.100
Provides-Extra: generator
Requires-Dist: anthropic>=0.40; extra == "generator"
Provides-Extra: openai
Requires-Dist: openai>=1.0; extra == "openai"
Provides-Extra: gemini
Requires-Dist: google-genai>=1.0; extra == "gemini"
Provides-Extra: all-providers
Requires-Dist: anthropic>=0.40; extra == "all-providers"
Requires-Dist: openai>=1.0; extra == "all-providers"
Requires-Dist: google-genai>=1.0; extra == "all-providers"
Dynamic: license-file

# CDD-CMDB

**A Configuration Management Database defined entirely as a test suite.**

This repository does not contain a CMDB. It contains the *specification* for one: a comprehensive set of tests that define the required behaviors, interfaces, data models, and invariants. Any implementation that passes the tests is a valid CMDB instance — whether it's generated by AI, hand-written, or assembled from existing services.

## Why

Traditional CMDB products are monolithic, hard to customize, and create vendor lock-in. This project inverts the model:

- **Ship tests, not code.** The test suite is the product. Implementations are disposable.
- **Generate on demand.** The included generator uses Claude to produce a passing implementation from scratch, targeting any backend stack.
- **Upgrade by re-testing.** Pull new test suites and regenerate. No migrations — new instances inherently comply.

## Quickstart

### One command (demo script)

```bash
git clone <repo-url> && cd cdd-cmdb
./demo.sh
```

This installs dependencies, starts the reference CMDB server, runs the validation suite, and leaves the server running for you to interact with. No API keys required.

### One command (Docker)

```bash
docker compose up --build
```

Starts the server and runs the full test suite in containers. Exit code 0 = compliant.

### Manual

```bash
pip install -e ".[generator]"

# Generate a CMDB (requires ANTHROPIC_API_KEY)
export ANTHROPIC_API_KEY=sk-ant-...
python -m generator --profile minimal

# Or validate your own implementation
CMDB_BASE_URL=http://localhost:8080 pytest suites/core --tb=short -q
```

## Test Suites

Tests are organized into modules, each covering a distinct capability:

| Suite | What it specifies |
|---|---|
| `core/` | CI CRUD, relationships, schema validation |
| `search/` | Full-text search, attribute filtering, wildcards, sorting, pagination |
| `diff/` | Attribute-level change diffs, point-in-time snapshots, time-range queries |
| `reconciliation/` | Source-based reconciliation (new/updated/unchanged/stale detection) |
| `tags/` | Tag CRUD, tag-based search, tag listing with counts |
| `ttl/` | Per-CI time-to-live, expiry sweep, status filtering |
| `webhooks/` | Webhook subscriptions, test pings, delivery history |
| `security/` | Injection resistance (SQL, XSS, NoSQL, template, path traversal), auth, RBAC |
| `discovery/` | Bulk CI import, source metadata |
| `performance/` | Latency SLAs per operation, throughput under bulk load |
| `governance/` | Runtime validation policies (required attributes, allowed values) |
| `audit/` | Immutable CI change history (create/update/delete events) |
| `graph/` | Multi-hop impact analysis, dependency traversal, cycle safety |

## Profiles

Profiles are compliance tiers. Each selects a subset of suites:

| Profile | Suites | Use case |
|---|---|---|
| `minimal` | core | MVP — prove basic CRUD works |
| `standard` | core, discovery, audit, graph, search, diff, reconciliation, tags, ttl, webhooks | Production-grade with full data model |
| `enterprise` | all | Full compliance including security, performance, governance |

Run a profile:

```bash
CMDB_BASE_URL=http://localhost:8080 pytest suites/core suites/discovery suites/audit suites/graph suites/search suites/diff suites/reconciliation suites/tags suites/ttl suites/webhooks --tb=short -q
```

## The Generator

The generator is a CLI that automates the generate-test-fix loop:

1. Reads the OpenAPI spec, JSON schemas, and test suite source
2. Prompts an LLM to produce a complete server implementation
3. Starts the server, runs the test suite against it
4. On failure, feeds errors back to the LLM and iterates
5. Repeats until all tests pass or `--max-iterations` is exhausted

```bash
python -m generator --profile minimal                          # FastAPI + SQLite (default)
python -m generator --profile standard --backend python/flask/sqlite
python -m generator --profile enterprise --model claude-opus-4-6 --max-iterations 10
python -m generator --output ./my-cmdb --port 9000
```

The generated server is standalone with no runtime dependency on this repository.

### Multi-Backend Support

Generate implementations in different languages, frameworks, and databases:

```bash
python -m generator --backend python/fastapi/sqlite          # default
python -m generator --backend python/flask/postgres
python -m generator --backend go/gin/sqlite
python -m generator --backend node/express/sqlite
python -m generator --backend node/express/mongodb
python -m generator --backend node/fastify/sqlite
python -m generator --list-backends                          # show all known backends
```

Custom backends are also supported — any `language/framework/database` triple works.

### Multi-Model Support

Use any LLM provider, not just Anthropic:

```bash
# Anthropic (default)
python -m generator --model claude-sonnet-4-6

# OpenAI
pip install openai
python -m generator --model gpt-4o

# Google Gemini
pip install google-genai
python -m generator --model gemini-2.0-flash

# Ollama (local, air-gapped)
python -m generator --model ollama/llama3

# LM Studio (local)
python -m generator --model lmstudio/default

# Explicit provider override
python -m generator --model my-custom-model --provider openai
```

Provider is auto-detected from model name prefix. Install the appropriate SDK:
`pip install -e ".[openai]"`, `pip install -e ".[gemini]"`, or `pip install -e ".[all-providers]"`.

### Caching

After a successful generation, the artifact is cached. Subsequent runs with the same profile + backend + unchanged tests will restore from cache instantly:

```bash
python -m generator --profile minimal          # generates and caches
python -m generator --profile minimal          # instant restore from cache
python -m generator --profile minimal --no-cache   # force regeneration
python -m generator --clear-cache              # delete all cached artifacts
```

Cache is invalidated automatically when specs, tests, or harness code change.

### Compliance Badges

Generate SVG badges showing which compliance tiers your instance satisfies:

```bash
python -m generator --badge                           # badge in output dir
python -m generator --badge --badge-dir ./badges      # custom badge dir
```

Produces `badge-{profile}.svg` and `compliance-{profile}.json`.

## API Surface

The test suites collectively define the following REST API:

### Configuration Items

| Method | Endpoint | Description |
|---|---|---|
| `POST` | `/cis` | Create a CI |
| `GET` | `/cis` | List/query CIs (supports `type`, `name`, `limit`, `offset`) |
| `GET` | `/cis/{id}` | Get a CI by ID |
| `PUT` | `/cis/{id}` | Full-replacement update |
| `DELETE` | `/cis/{id}` | Delete (409 if relationships exist) |
| `POST` | `/cis/bulk` | Bulk create |
| `GET` | `/cis/{id}/history` | Audit trail |
| `GET` | `/cis/{id}/relationships` | Direct relationships (filterable by `direction`, `type`) |
| `GET` | `/cis/{id}/impact` | Transitive downstream traversal (`depth`, `relationship_types`) |
| `GET` | `/cis/{id}/dependencies` | Transitive upstream traversal |
| `GET` | `/cis/search` | Full-text search, attribute filters, wildcards, sorting |
| `GET` | `/cis/{id}/diff` | Changes in a time range (`from`, `to`) |
| `GET` | `/cis/{id}/history/{entry_id}/diff` | Attribute-level diff for a specific audit entry |
| `GET` | `/cis/{id}/history/{entry_id}/snapshot` | Full CI state at a specific audit entry |
| `POST` | `/cis/reconcile` | Reconcile CIs from an external source |
| `PUT` | `/cis/{id}/tags` | Set tags on a CI |
| `GET` | `/cis/{id}/tags` | Get tags for a CI |
| `DELETE` | `/cis/{id}/tags/{tag}` | Remove a single tag |
| `GET` | `/tags` | List all tags with usage counts |
| `PUT` | `/cis/{id}/ttl` | Set time-to-live on a CI |
| `GET` | `/cis/{id}/ttl` | Get TTL info for a CI |
| `DELETE` | `/cis/{id}/ttl` | Remove TTL from a CI |
| `POST` | `/cis/expire` | Sweep and expire CIs past their TTL |

### Webhooks

| Method | Endpoint | Description |
|---|---|---|
| `POST` | `/webhooks` | Register a webhook subscription |
| `GET` | `/webhooks` | List all webhooks |
| `GET` | `/webhooks/{id}` | Get a webhook |
| `DELETE` | `/webhooks/{id}` | Delete a webhook |
| `POST` | `/webhooks/{id}/test` | Trigger a test ping |
| `GET` | `/webhooks/{id}/deliveries` | Delivery history for a webhook |

### Relationships

| Method | Endpoint | Description |
|---|---|---|
| `POST` | `/relationships` | Create a relationship between two CIs |
| `GET` | `/relationships/{id}` | Get a relationship |
| `DELETE` | `/relationships/{id}` | Delete a relationship |

### Governance

| Method | Endpoint | Description |
|---|---|---|
| `POST` | `/policies` | Create a validation policy |
| `GET` | `/policies` | List policies |
| `DELETE` | `/policies/{id}` | Delete a policy |

### System

| Method | Endpoint | Description |
|---|---|---|
| `GET` | `/health` | Liveness check |

## Environment Variables

| Variable | Purpose | Default |
|---|---|---|
| `CMDB_BASE_URL` | Target instance for tests | `http://localhost:8080` |
| `HYPOTHESIS_PROFILE` | `ci` (fast) or `release` (thorough) | `ci` |
| `CMDB_AUTH_ENABLED` | Enable auth test suite | unset (skipped) |
| `CMDB_READONLY_TOKEN` | Token for RBAC read-only tests | unset (skipped) |
| `CMDB_SLA_CRUD_MS` | Max latency for single CRUD ops | `500` |
| `CMDB_SLA_LIST_MS` | Max latency for list queries | `1000` |
| `CMDB_SLA_REL_QUERY_MS` | Max latency for relationship queries | `1000` |
| `CMDB_SLA_HEALTH_MS` | Max latency for health check | `200` |
| `CMDB_SLA_BULK_100_MS` | Max time for bulk create of 100 CIs | `5000` |
| `CMDB_SLA_SEQ_50_MS` | Max time for 50 sequential CRUD cycles | `10000` |
| `ANTHROPIC_API_KEY` | Required for Anthropic models | — |
| `OPENAI_API_KEY` | Required for OpenAI models | — |
| `GOOGLE_API_KEY` | Required for Gemini models | — |
| `OLLAMA_BASE_URL` | Ollama API endpoint | `http://localhost:11434/v1` |
| `LMSTUDIO_BASE_URL` | LM Studio API endpoint | `http://localhost:1234/v1` |

## Project Structure

```
specs/              OpenAPI 3.1 + JSON Schema — the API contract
suites/             pytest test suites — the specification
harness/            Test infrastructure (HTTP client, fixtures, Hypothesis strategies)
profiles/           Compliance tier definitions (minimal / standard / enterprise)
generator/          AI-driven implementation generator
conftest.py         Shared pytest fixtures
pyproject.toml      Python project config
```

## Contributing

The specification evolves by adding or refining tests. When contributing:

1. Tests define behavior, not implementation. Never import implementation code.
2. All CMDB interaction goes through `harness/client.py`.
3. New endpoints need corresponding methods in the client and factory fixtures in `conftest.py`.
4. Use property-based tests (`@given`) for invariants, example-based tests for specific scenarios.
5. Add new suites to the appropriate profile(s) in `profiles/`.

## License

[Add license here]
