HunterX v7 Target Intelligence Database — Architecture & Reference
Status: Ratified (Sprint 006.8) Version: 1.0.0 Owner: HunterX Architecture Council
1. Purpose / Scope
The Target Intelligence Database (TIDB) is the canonical relational store of HunterX v7: every target, asset, finding, piece of evidence, mission, report, user and audit record has exactly one source of truth here. This document describes the system-of-record layer built in Sprint 006.8:
- Entities — 87 typed domain entities under
src/hunterx/domain/entities/tidb/plus 6 legacy v6 entities retrofitted with the TIDB envelope. - ORM models — a SQLAlchemy model per entity under
src/hunterx/infrastructure/db/sql/tidb_models/, one table per model (93 tables total). - Persistence — a generic registry + row mapper that turns any entity into rows and back, implemented by a generic SQL CRUD repository and an in-memory twin.
- Versioning & audit — an immutable history trail (audit log, field-level change history, version history, timeline) written by a SQLAlchemy listener.
- Migrations — Alembic environment and an autogenerated baseline.
- Validation — envelope and field-level validation services.
Hard constraints:
- No behavior change. This sprint changes no security tool, capability, AI provider or Mission behavior.
- Entities are pure. The TIDB entities are side-effect-free dataclasses; storage adapters do the persistence.
- Swap-able storage. The same repository port is implemented for SQL and for in-memory so the platform runs with zero external services.
Scope: src/hunterx/domain/entities/tidb/,
src/hunterx/domain/ports/tidb_repositories.py,
src/hunterx/domain/services/validation.py,
src/hunterx/infrastructure/db/sql/tidb_models/,
src/hunterx/infrastructure/db/sql/{registry,mapping,crud,memory,versioning}.py,
and alembic/.
Out of scope: the Knowledge Graph, object store, cache, and queue; the mission/workflow/reporting pipelines that consume TIDB.
2. Design Goals
- Every record versioned. Writes are immutable history: audit entries, field-level change history, version numbers and timeline events are written transactionally with the write that caused them.
- One mapping, many stores. The row mapper derives from Python type hints, so adding an entity costs nothing beyond defining the entity and its ORM model.
- ULID keys, UTC stamps. Identifiers are 26-char ULIDs; all timestamps are UTC ISO-8601 strings; confidence values are bounded floats.
- Soft delete by default. Deletion sets
deleted_atand bumps versioning counters; hard delete is explicit.
3. Entity Model
3.1 The Envelope
Every TIDB entity carries the USS envelope (docs/bible/08 - Unified Security
Schema.md, docs/bible/09 - Database Design.md §3):
| Field | Type | Notes |
|---|---|---|
id |
str |
26-char ULID, primary key |
created_at |
str |
UTC ISO-8601, set on insert |
updated_at |
str |
UTC ISO-8601, set on insert/update |
first_seen |
str | None |
first observed timestamp |
last_seen |
str | None |
last observed timestamp |
version |
int |
optimistic-lock counter, starts at 1 |
revision |
int |
content-revision counter, starts at 1 |
schema_version |
int |
schema version of the record, starts at 1 |
deleted_at |
str | None |
soft-delete marker |
meta |
dict |
extensible per-entity metadata |
Envelope fields are kw_only=True in the dataclasses so entity-specific
fields never collide with them.
3.2 Entity Groups
The 87 entities are grouped in 11 modules mirroring the ORM package:
| Module | Entities (count) |
|---|---|
core |
organization, program, project, team, engagement, asset-group, asset, service-group (8) |
network |
ip-address, network, subnet, domain-name, hostname, dns-record, port, service (8) |
web |
web-application, web-route, web-parameter, http-request, http-response, cookie, header, ssl-certificate, ssl-certificate-chain (9) |
api |
api-endpoint, api-parameter, api-response-schema, api-authentication, api-key (5) |
finding |
finding, vulnerability, exploit, cve, cwe, cvss-vector, poc, attachment (8) |
security |
security-finding, detection-rule, firewall-rule, iam-role, iam-policy, identity, credential, secret, key, permission, trust-boundary, security-policy, compliance-control (13) |
knowledge |
mitre-technique, mitre-tactic, threat-actor, campaign, threat-intelligence-feed, io-c (6) |
execution |
mission, mission-plan, checkpoint, task, task-run, command, tool, tool-run, work-flow, work-flow-step, job, schedule (12) |
reporting |
report, report-section, report-template, analytics-dashboard (4) |
audit |
audit-log, version-history, change-history, timeline-event, event (5) |
user |
user, user-role, api-token (3) |
4. ORM Models
src/hunterx/infrastructure/db/sql/tidb_models/ defines one SQLAlchemy model
per entity (TidbX for entity X). All models inherit TidbModelMixin
(tidb_models/_base.py), which maps the envelope onto the get_base()
declarative base: String(26) ULID primary keys, JSON columns for JSONB
compatibility, FKs between related tables, UniqueConstraint and composite
Index objects where the domain requires them.
- 87
tidb_*tables from TIDB entities + 6 legacyhunterx_*tables = 93 tables registered on the shared metadata. - Model docstrings state the entity they mirror;
envelope_dict()renders a model back to its entity shape. - The models and entities share names, so the registry in §5 can associate them without configuration.
5. Registry & Row Mapper
5.1 Registry (db/sql/registry.py)
ENTITY_TO_MODEL / MODEL_TO_ENTITY are derived from class names
(EntityX ↔ XModel). Helpers: entity_class(), model_class(),
all_entities() (returns all 87 entity classes).
5.2 Row Mapper (db/sql/mapping.py)
RowMapper(entity_cls) maps between an entity and its ORM model:
new_row(entity)— build a model instance from an entity.apply(entity, row)— copy entity fields onto an existing row.to_entity(row)— build an entity from a row.to_row/apply_entity— the reverse directions.
Enums are coerced by value both ways (Enum(value)); type hints are resolved
once per entity class and cached (__tidb_hints__).
6. Repository Port & Implementations
6.1 Port (domain/ports/tidb_repositories.py)
TidbRepository[E] is a Generic ABC with: get, get_or_raise, save,
save_many, delete, soft_delete, count, list (paginated + ordered),
list_by, and stream (batch iteration for large tables).
TidbRepositoryFactory builds and caches repositories per entity.
6.2 SQL repository (db/sql/crud.py)
SqlCrudRepository(session_factory, entity_cls) implements the port:
- upsert on
id(select-then-insert/update), soft_deletesetsdeleted_atand bumpsversion/revision,list/list_byaccept only whitelisted sort columns (_SAFE_ORDER),streamiterates withyield_perbatching,save/save_manyrun the envelope validator first and raiseDomainValidationErroron invalid entities.
SqlTidbRepositoryFactory builds repositories from session_factory and
exposes available_entities.
6.3 In-memory repository (db/sql/memory.py)
InMemoryCrudRepository(entity_cls) is a dict-backed implementation with the
same semantics (soft delete included), giving a zero-dependency mode for
tests and single-node operation. Sorting uses a stable
(value, id) tiebreaker so records created in the same millisecond sort
deterministically. InMemoryTidbRepositoryFactory mirrors the SQL factory.
7. Versioning & Audit
db/sql/versioning.py installs a VersioningListener on the SQLAlchemy
SessionFactory (install_versioning(session_factory)). On every before_flush
it records, in the same transaction:
AuditLogModel— one entry per create/update/soft-delete/hard-delete.ChangeHistoryModel— field-level diffs (skipsid,created_at,updated_at,version,revision).VersionHistoryModel— a version snapshot per write.TimelineEventModel— a timeline event per write.
Audit models are themselves excluded from versioning to prevent recursion.
8. Migrations (Alembic)
The alembic/ directory contains the migration environment:
alembic/env.pyimports both legacyhunterx.modelsand v7hunterx.tidb_modelsintoget_base().metadata, appliescompare_type=True, honors aHUNTERX_DB_URLoverride, and forcessrc/onto the front ofsys.path(the repo-root legacyhunterx/would otherwise shadow the v7 package on Windows).alembic/versions/4302b30cb7c7_tidb_baseline.pyis the autogenerated baseline: 93create_table+ 93drop_tableoperations.
Workflow:
python -m alembic upgrade head # apply
python -m alembic downgrade base # roll back to empty schema
python -m alembic check # assert models and DB are in sync
python -m alembic revision --autogenerate -m "<change>" # new migration
9. Validation
domain/services/validation.py defines the validation layer:
TidbValidatorABC andTidbValidationResult/ValidationIssue.EnvelopeTidbValidator— validates the shared envelope: ULIDid, UTC ISO-8601 timestamps, positiveversion/revision/schema_version.EntityTidbValidator— composes the envelope checks with per-field type and enum checks against the entity’s dataclass field hints.
TidbValidationResult.raise_if_invalid() raises DomainValidationError with
the collected issues; the SQL repository invokes the envelope validator on
save/save_many.
10. Module Reference
| Module | Contents |
|---|---|
domain/entities/tidb/ |
87 pure dataclass entities in 11 modules |
domain/ports/tidb_repositories.py |
TidbRepository, TidbRepositoryFactory |
domain/services/validation.py |
TidbValidator, EnvelopeTidbValidator, EntityTidbValidator |
infrastructure/db/sql/tidb_models/ |
87 ORM models + TidbModelMixin + Base |
infrastructure/db/sql/registry.py |
entity ↔ model registry |
infrastructure/db/sql/mapping.py |
RowMapper |
infrastructure/db/sql/crud.py |
SqlCrudRepository, SqlTidbRepositoryFactory |
infrastructure/db/sql/memory.py |
InMemoryCrudRepository, InMemoryTidbRepositoryFactory |
infrastructure/db/sql/versioning.py |
VersioningListener, install_versioning |
alembic/ |
env + baseline migration 4302b30cb7c7 |
11. Verification
Gates at sprint close:
python -m pytest tests/unit tests/integration tests/component— 576 passed (526 baseline + 41 TIDB tests + 9 validation tests).python -m ruff check src/hunterx tests alembic— clean.python -m alembic upgrade head && python -m alembic downgrade base— applied and rolled back cleanly.python -m alembic check— “No new upgrade operations detected”.
TIDB tests live in tests/unit/test_tidb_registry_mapper.py,
tests/unit/test_tidb_in_memory_repository.py,
tests/unit/test_tidb_validation.py,
tests/integration/test_tidb_sql_repository.py,
tests/integration/test_tidb_versioning.py,
tests/integration/test_tidb_alembic.py.
12. References
docs/bible/08 - Unified Security Schema.md— USS envelopedocs/bible/09 - Database Design.md— TIDB core tables, indexes, history, retentiondocs/bible/02 - Architecture.md§5.15 — TIDB within the platformdocs/v7-foundation.md— v7 core foundation module reference