Go package structure and dependency rules
This document makes package ownership reviewable before the Phase 1 module exists. Directories should be created as implementation reaches them; placeholder Go code is avoided because exported types would prematurely freeze draft contracts.
Ownership
| Package | Owns |
|---|---|
cmd/guardrailsd | process composition only: config loading, wiring, server lifecycle, signals |
internal/app | application assembly and readiness; no domain rules |
internal/model | canonical immutable value objects and validation invariants |
internal/evaluation | orchestration, detector scheduling, composition, span conflict resolution, transformations |
internal/policy | authoring parse/validate, CEL environment, DAG compiler, snapshots, trusted binding resolution |
internal/correlation | PostgreSQL repositories, approved correlation/provenance model, deterministic snapshot compilation |
internal/checks/pii | generic and Australian PII detection/evidence, not policy actions |
internal/checks/credentials | credential candidates, entropy/context/allowlists; no live remote validation |
internal/checks/jailbreak | jailbreak and prompt-injection evidence |
internal/checks/safety | safety classification evidence |
internal/adapter/canonical | direct API request mapping |
internal/adapter/portkey | Portkey webhook/full replacement mapping only |
internal/adapter/protocol | provider payload extraction and reconstruction |
internal/transport/http | Gin routes, auth middleware boundary, limits, problem responses |
internal/platform/config | operator-owned runtime configuration |
internal/platform/telemetry | safe logs, metrics, traces, audit sink adapters |
Keep registries by extension kind rather than a universal plugin registry. Most
code remains under internal; do not publish a Go SDK/plugin API until its
compatibility contract is deliberately frozen.
Dependency direction
cmd/guardrailsd
│
▼
internal/app ─────▶ transport/http ─────▶ adapter/*
│ │
├────────────▶ evaluation ◀────────────┘
│ │
│ ├────▶ model
│ ├────▶ policy ─────▶ model
│ └────▶ detector interfaces in evaluation/model
│
├────────────▶ correlation ───────────▶ policy/model snapshot inputs
├────────────▶ checks/* ──────────────▶ model
└────────────▶ platform/*Domain packages never import Gin, Portkey types, SQL, protobuf transport types, or
process-global configuration. Detectors never import the composer. Adapters may
depend on canonical model interfaces but the model cannot depend on adapters.
PostgreSQL repositories live in internal/correlation, not internal/model or the
evaluator's request path. That package compiles approved rows into snapshot inputs;
the evaluator depends on the resulting immutable model, never the repository.
HTTP server boundary
internal/transport/http constructs a Gin engine and returns net/http.Handler.
cmd/guardrailsd or internal/app owns http.Server configuration including
read-header, request-read, response-write, and idle timeouts, maximum body size,
graceful shutdown, and readiness. Gin context must not escape route handlers.
Contract generation
OpenAPI, JSON Schema, and protobuf are reviewed source artefacts under api/.
Generated code goes to a clearly marked generated tree and is reproducible; hand-
written domain types do not alias generated transport types. Contract drift tests
map both directions and exercise unknown/invalid values explicitly.
Test placement
- package-local unit, property, and fuzz tests sit with implementation;
- gateway/protocol goldens live under
test/contract; - execution-neutral detector/composer cases live under
test/conformance; - benchmark corpus manifests live under
test/evaldata, while restricted data remains outside Git under its approved governance and access controls.