Metadata-Version: 2.4
Name: domain-resolution-compiler
Version: 1.0.0
Summary: Domain Resolution Compiler — diagnostic tool that compiles public domain data into a unified report.
Author: DRC Project
License: MIT
Keywords: dns,whois,rdap,ssl,diagnostics,domain
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: System Administrators
Classifier: Intended Audience :: Information Technology
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: Name Service (DNS)
Classifier: Topic :: System :: Networking
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: dnspython>=2.6
Requires-Dist: httpx>=0.27
Requires-Dist: python-whois>=0.9
Requires-Dist: cryptography>=42.0
Requires-Dist: jinja2>=3.1
Requires-Dist: click>=8.1
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Requires-Dist: ruff>=0.4; extra == "dev"
Requires-Dist: pre-commit>=3.7; extra == "dev"

# DRC — Domain Resolution Compiler

**Status:** v0.1.0 — Pre-Alpha (Phase 3 complete)

DRC is a read-only diagnostic tool that queries public infrastructure — RDAP, WHOIS, DNS, Certificate Transparency logs, TLS, and HTTP — and compiles the results into a single actionable report. It runs seven diagnostic modules (modules 4–7 concurrently), cross-references their outputs, and applies a rule-based synthesis engine to identify the root cause of domain, DNS, or SSL problems. No credentials required. No records modified. Everything it queries is publicly accessible internet data.

---

## Required reading

Before changing anything in this repository, read both documents in order:

1. **[`DRC_FOUNDATION.md`](DRC_FOUNDATION.md)** — Architecture, module definitions, synthesis engine rules, project scope and boundaries.
2. **[`DRC_PRINCIPLES.md`](DRC_PRINCIPLES.md)** — Design constraints, safeguards, rate limiting policy, input validation contract, and the Definition of Done. These are non-negotiable.

Neither document is complete without the other.

---

## What this is

When a domain isn't working, the diagnostic data lives in seven different systems. DRC queries all of them in one pass, cross-references the results, and tells you what's actually broken — instead of leaving you to mentally correlate `dig`, `whois`, `curl`, and `crt.sh` output yourself.

Every report begins with the URL entry for the domain being analyzed. Where a registry redacts registrant data, DRC identifies the cause where determinable — a registry/regulatory policy or a named privacy service — and otherwise reports the registry's own text unaltered. Every other published record for the domain is reported as available. See `DRC_PRINCIPLES.md` §Privacy and Data Handling and `DRC_DECISIONS.md` D1 for the full rule.

## What this is not

- A DNS management tool. It cannot edit records.
- A monitor. It runs on demand, not continuously.
- A vulnerability scanner. It looks at configuration, not exploits.

---

## Canonical test fixtures

Two real-world domains are designated permanent regression anchors for the synthesis engine:

| Domain | Known state | Role |
|---|---|---|
| `xenoxylon.com` | Healthy — Wix-hosted, all records published, TLS valid | Positive control: synthesis must return **OK** or **WARNING** (live state may show partial propagation); unit test holds strict **OK** with 100% propagation mocked |
| `observerprime.ai` | Provisioned Apr 2026 — A records present, propagation-in-progress | WARNING-path live fixture; historical CRITICAL state preserved in JSON fixtures |

**observerprime.ai — two-phase history:**

- **Oct 2025 – Apr 2026 (broken phase):** Wix zone was created but not provisioned. SOA record present; A, AAAA, and CNAME records absent. Synthesis returned `CRITICAL / zone_provisioning_failure`. Historical DNS responses from this phase are preserved in `tests/fixtures/observerprime_historical/` as module-level JSON fixtures.
- **Apr 2026+ (current state):** Wix zone was provisioned. A records now present; domain exhibits propagation-in-progress behavior. Live integration tests assert WARNING-path behavior.

`zone_provisioning_failure` synthesis rule coverage is provided by the fixture-based unit test `test_historical_observerprime_fixtures_produce_zone_provisioning_failure` in `tests/test_synthesis.py`, which loads the historical JSON fixtures and runs synthesis offline. This test is permanent and does not depend on the domain's live DNS state.

When DRC's diagnosis disagrees with the known state of either domain, the diagnosis is wrong — not the ground truth. Do not weaken these assertions. If a future code change causes them to fail, surface the disagreement and decide deliberately.

---

## Install

**From PyPI (recommended):**

```bash
pip install domain-resolution-compiler
drc --help
```

**Docker:**

```bash
# CLI summary
docker run --rm ghcr.io/xenoxylon/drc drc scan xenoxylon.com --format cli

# HTML report saved to the current directory
docker run --rm -v "$(pwd):/out" ghcr.io/xenoxylon/drc \
  drc scan xenoxylon.com --format html --output /out/report.html
```

No credentials required for either install path.

---

## Development setup

You need Python 3.10 or newer:

```bash
python3 --version
```

From the project root (the directory containing `pyproject.toml`):

```bash
python3 -m venv .venv
source .venv/bin/activate          # macOS/Linux
# .venv\Scripts\activate           # Windows PowerShell

pip install -e ".[dev]"
```

The `-e` flag means "editable install" — code changes take effect immediately without reinstalling. The `[dev]` extra pulls in `pytest` and `ruff`.

Verify the CLI is wired up:

```bash
drc --help
```

---

## Running the tests

```bash
pytest
```

The full suite (unit + synthesis) runs in under 1 second with no network traffic. Integration tests that make live network calls are gated behind the `--integration` flag:

```bash
# Live-network scan of canonical fixtures (~30-120s, requires internet)
pytest --integration -v
```

To run a single test file:

```bash
pytest tests/test_synthesis.py -v
```

---

## Usage

```bash
# Single domain — CLI summary with ANSI color
drc scan observerprime.ai

# Multiple domains (max 5 per invocation)
drc scan observerprime.ai xenoxylon.com

# URL input — hostname is extracted automatically; a notice is printed to stderr
drc scan https://example.com

# IDN / internationalized domain
drc scan münchen.de

# Output formats
drc scan observerprime.ai --format html --output report.html
drc scan observerprime.ai --format json --output data.json
drc scan observerprime.ai --format cli

# Baseline comparison — diff current scan against a previously saved JSON report
drc scan observerprime.ai --format json --output baseline.json
drc scan observerprime.ai --baseline baseline.json          # CLI diff
drc scan observerprime.ai --baseline baseline.json --format html --output diff.html

# Severity-regression monitoring — exits 1 if any matched domain regressed, 0 if stable
drc scan example.com --baseline known_good.json --format json --output /dev/null \
  || alert "drc: example.com regressed"
```

### JSON output schema

See [`docs/json_schema.md`](docs/json_schema.md) for the full Phase 3 schema reference.

The top-level shape:

```json
{
  "drc_version": "0.1.0",
  "schema_version": "1.0",
  "scan_timestamp": "2026-05-11T12:34:56+00:00",
  "domains": [
    {
      "input":     "https://Example.COM",
      "normalized":"example.com",
      "display":   "example.com",
      "url":       "https://example.com",
      "modules":   { "registrar": {...}, "delegation": {...}, ... },
      "synthesis": { "severity": "OK", "root_cause": "...", ... },
      "errors":    []
    }
  ]
}
```

### Input validation

DRC validates every domain argument before scanning:

| Input | Behaviour |
|-------|-----------|
| `https://example.com` | Hostname extracted; notice to stderr |
| `ftp://example.com` | Rejected — only http(s) schemes are stripped; others are rejected |
| `example.com, other.com` | Rejected — pass as separate arguments |
| `*.example.com` | Rejected — wildcards not supported |
| `user@example.com` | Rejected — not a domain name |
| `192.168.1.1` | Rejected — IP addresses not accepted |
| `localhost` | Rejected — not a valid scan target |
| `münchen.de` | Accepted and normalized to punycode |
| More than 5 domains | Rejected — 5-domain per-invocation cap |

---

## Project layout

```
drc/
├── drc/                   ← the actual Python package
│   ├── cli.py             ← `drc` command entry point
│   ├── compiler.py        ← async pipeline orchestrator (arun/run)
│   ├── validate.py        ← input validation + IDN normalization
│   ├── rate_limiter.py    ← shared rate limiter + http_get_with_retry
│   ├── synthesis.py       ← rule engine that produces the diagnosis
│   ├── render.py          ← HTML / JSON / CLI formatters
│   ├── modules/           ← one file per pipeline stage
│   ├── patterns/          ← host provider fingerprints (JSON)
│   ├── resolvers/         ← global resolver list (JSON)
│   └── templates/         ← Jinja2 HTML report template
├── tests/
│   ├── test_integration.py ← live-network tests (--integration flag)
│   └── ...                ← unit + synthesis tests
├── docs/
│   ├── json_schema.md     ← Phase 3 JSON output schema reference
│   └── decisions/         ← architecture decision records (ADRs)
├── pyproject.toml         ← project + dependency manifest
├── DRC_FOUNDATION.md      ← architecture document — authoritative
└── DRC_PRINCIPLES.md      ← design constraints — non-negotiable
```

---

## License

MIT.
