Domain Models
June 9, 2026 · View on GitHub
Complete reference for domain entities, value objects, and enums. All definitions are derived from the TypeSpec source of truth (tsp/). Generated TypeScript types live in packages/core/src/domain/generated/output.ts.
Base Entity
All domain entities extend BaseEntity, which provides identity and timestamp fields.
export type UUID = string;
export type BaseEntity = {
id: UUID;
createdAt: any;
updatedAt: any;
};
export type SoftDeletableEntity = BaseEntity & {
deletedAt?: any;
};
Entities
Feature
The central aggregate root representing a piece of work progressing through the SDLC lifecycle. Feature encapsulates all related entities (Messages, Plan, Artifacts) and serves as the boundary for transactional consistency.
export type Feature = BaseEntity & {
name: string;
userQuery: string;
slug: string;
description: string;
repositoryPath: string;
branch: string;
lifecycle: SdlcLifecycle;
messages: Message[];
plan?: Plan;
relatedArtifacts: Artifact[];
agentRunId?: string;
specPath?: string;
repositoryId?: UUID;
fast: boolean;
push: boolean;
openPr: boolean;
approvalGates: ApprovalGates;
worktreePath?: string;
pr?: PullRequest;
parentId?: UUID;
attachments?: Attachment[];
};
Plan
Implementation plan for a feature containing tasks, artifacts, requirements, and optional scheduling data.
export type Plan = BaseEntity & {
overview: string;
requirements: Requirement[];
artifacts: Artifact[];
tasks: Task[];
state: PlanState;
workPlan?: GanttViewData;
};
Task
Discrete unit of work within a Plan.
export type Task = BaseEntity & {
title?: string;
description?: string;
dependsOn: Task[];
actionItems: ActionItem[];
baseBranch: string;
state: TaskState;
branch: string;
};
ActionItem
Granular, atomic step within a Task.
export type ActionItem = BaseEntity & {
name: string;
description: string;
branch: string;
dependsOn: ActionItem[];
acceptanceCriteria: AcceptanceCriteria[];
};
AcceptanceCriteria
export type AcceptanceCriteria = BaseEntity & {
description: string;
verified: boolean;
};
Artifact
Generated document or file attached to a Feature.
export type Artifact = BaseEntity & {
name: string;
type: string;
category: ArtifactCategory;
format: ArtifactFormat;
summary: string;
path: string;
state: ArtifactState;
};
Requirement
export type Requirement = BaseEntity & {
slug: string;
userQuery: string;
type: RequirementType;
researches: Research[];
};
Research
export type Research = BaseEntity & {
topic: string;
state: ResearchState;
summary: string;
artifacts: Artifact[];
};
Message
export type Message = BaseEntity & {
role: MessageRole;
content: string;
options?: string[];
answer?: string;
selectedOption?: number;
};
Settings
Global Shep platform settings stored as a singleton.
export type Settings = BaseEntity & {
models: ModelConfiguration;
user: UserProfile;
environment: EnvironmentConfig;
system: SystemConfig;
agent: AgentConfig;
notifications: NotificationPreferences;
workflow: WorkflowConfig;
featureFlags?: FeatureFlags;
onboardingComplete: boolean;
};
Repository
export type Repository = SoftDeletableEntity & {
name: string;
path: string;
};
Value Objects
ModelConfiguration
export type ModelConfiguration = {
default: string; // Default model identifier for all agents
};
UserProfile
export type UserProfile = {
name?: string;
email?: string;
githubUsername?: string;
};
EnvironmentConfig
export type EnvironmentConfig = {
defaultEditor: EditorType;
shellPreference: string;
};
SystemConfig
export type SystemConfig = {
autoUpdate: boolean;
logLevel: string;
};
AgentConfig
export type AgentConfig = {
type: AgentType;
authMethod: AgentAuthMethod;
token?: string;
};
ApprovalGates
export type ApprovalGates = {
allowPrd: boolean;
allowPlan: boolean;
allowMerge: boolean;
};
PullRequest
export type PullRequest = {
url: string;
number: number;
status: PrStatus;
commitHash?: string;
ciStatus?: CiStatus;
ciFixAttempts?: number;
ciFixHistory?: CiFixRecord[];
};
Attachment
export type Attachment = {
id: UUID;
name: string;
size: bigint;
mimeType: string;
path: string;
createdAt: any;
};
ApprovalGateDefaults
export type ApprovalGateDefaults = {
allowPrd: boolean;
allowPlan: boolean;
allowMerge: boolean;
pushOnImplementationComplete: boolean;
};
WorkflowConfig
export type WorkflowConfig = {
openPrOnImplementationComplete: boolean;
approvalGateDefaults: ApprovalGateDefaults;
ciMaxFixAttempts?: number;
ciWatchTimeoutMs?: number;
ciLogMaxChars?: number;
};
NotificationPreferences
export type NotificationPreferences = {
inApp: NotificationChannelConfig;
browser: NotificationChannelConfig;
desktop: NotificationChannelConfig;
events: NotificationEventConfig;
};
FeatureFlags
export type FeatureFlags = {
skills: boolean;
envDeploy: boolean;
debug: boolean;
};
GanttViewData
export type GanttViewData = {
tasks: GanttTask[];
startDate: any;
endDate: any;
};
export type GanttTask = {
id: UUID;
name: string;
start: any;
end: any;
dependencies: UUID[];
progress: number;
};
Enums
SdlcLifecycle
enum SdlcLifecycle {
Started = 'Started',
Analyze = 'Analyze',
Requirements = 'Requirements',
Research = 'Research',
Planning = 'Planning',
Implementation = 'Implementation',
Review = 'Review',
Maintain = 'Maintain',
Blocked = 'Blocked',
}
TaskState
enum TaskState {
Todo = 'Todo',
WIP = 'Work in Progress',
Done = 'Done',
Review = 'Review',
}
PlanState
enum PlanState {
Requirements = 'Requirements',
ClarificationRequired = 'ClarificationRequired',
Ready = 'Ready',
}
ArtifactCategory
enum ArtifactCategory {
PRD = 'PRD',
API = 'API',
Design = 'Design',
Other = 'Other',
}
ArtifactFormat
enum ArtifactFormat {
Markdown = 'md',
Text = 'txt',
Yaml = 'yaml',
Other = 'Other',
}
ArtifactState
enum ArtifactState {
Todo = 'Todo',
Elaborating = 'Elaborating',
Done = 'Done',
}
RequirementType
enum RequirementType {
Functional = 'Functional',
NonFunctional = 'NonFunctional',
}
ResearchState
enum ResearchState {
NotStarted = 'NotStarted',
Running = 'Running',
Finished = 'Finished',
}
MessageRole
enum MessageRole {
Assistant = 'assistant',
User = 'user',
}
AgentType
enum AgentType {
ClaudeCode = 'claude-code',
GeminiCli = 'gemini-cli',
Aider = 'aider',
Continue = 'continue',
Cursor = 'cursor',
Dev = 'dev',
}
AgentAuthMethod
enum AgentAuthMethod {
Session = 'session',
Token = 'token',
}
EditorType
enum EditorType {
VsCode = 'vscode',
Cursor = 'cursor',
Windsurf = 'windsurf',
Zed = 'zed',
Antigravity = 'antigravity',
}
PrStatus
enum PrStatus {
Open = 'Open',
Merged = 'Merged',
Closed = 'Closed',
}
CiStatus
enum CiStatus {
Pending = 'Pending',
Success = 'Success',
Failure = 'Failure',
}
NotificationEventType
enum NotificationEventType {
AgentStarted = 'agent_started',
PhaseCompleted = 'phase_completed',
WaitingApproval = 'waiting_approval',
AgentCompleted = 'agent_completed',
AgentFailed = 'agent_failed',
PrMerged = 'pr_merged',
PrClosed = 'pr_closed',
PrChecksPassed = 'pr_checks_passed',
PrChecksFailed = 'pr_checks_failed',
}
ASPM (Feature 098)
The Application Security Posture Management module adds a unified
security domain anchored on Application. See
../architecture/aspm.md for the module
overview, ports, and ingestion flow.
Application (extended)
The existing Application entity gains four optional ASPM context
fields. The previous fields are unchanged.
export type Application = SoftDeletableEntity & {
// …existing fields…
criticality?: Criticality;
exposure?: Exposure;
dataClassification?: DataClassification;
businessUnit?: string;
};
SecurityFinding
Unified finding row produced by every ingestion adapter (SARIF v2.1.0,
CycloneDX 1.5+, AI-change graduation). Soft-deletable for audit; dedup
key is (applicationId, findingDomain, ruleId, locationPath, locationLine, cveId).
export type SecurityFinding = SoftDeletableEntity & {
applicationId: UUID;
serviceId?: UUID;
apiAssetId?: UUID;
cloudEnvironmentId?: UUID;
findingDomain: FindingDomain;
ruleId: string;
title: string;
description: string;
locationPath?: string;
locationLine?: number;
scannerRaw?: string;
scannerRawHash?: string;
rawSeverity: string;
canonicalSeverity: CanonicalSeverity;
cveId?: string;
cweId?: string;
owaspAsvsControlId?: string;
ownerId?: UUID;
state: FindingState;
currentRiskScoreId?: UUID;
workItemId?: UUID;
source: string;
discoveredAt: any;
lastSeenAt: any;
firstFixedAt?: any;
};
RiskScore
Append-only history of composite scores. SecurityFinding.currentRiskScoreId
points at the latest row.
export type RiskScore = BaseEntity & {
findingId: UUID;
total: number; // 0-100
breakdown: RiskScoreBreakdown;
computedAt: any;
inputsHash: string;
};
Owner / Team / BusinessUnit
export type Owner = SoftDeletableEntity & {
name: string;
handle?: string;
email?: string;
teamId?: UUID;
};
export type Team = SoftDeletableEntity & { name: string; businessUnitId?: UUID };
export type BusinessUnit = SoftDeletableEntity & { name: string };
Service / ApiAsset / CloudEnvironment
Adjacent asset entities covering non-application risk surfaces. Each
links back to an Application.
export type Service = SoftDeletableEntity & { applicationId: UUID; name: string };
export type ApiAsset = SoftDeletableEntity & {
applicationId: UUID;
name: string;
baseUrl?: string;
};
export type CloudEnvironment = SoftDeletableEntity & {
applicationId: UUID;
provider: string;
name: string;
};
RemediationCampaign
Query-shaped campaigns; progress is computed at read time.
export type RemediationCampaign = SoftDeletableEntity & {
name: string;
description: string;
targetQuery: FindingFilter;
status: CampaignStatus;
ownerId?: UUID;
dueDate?: any;
closedAt?: any;
};
SecurityPolicy
Calendar-day SLA windows per canonical severity.
export type SecurityPolicy = SoftDeletableEntity & {
name: string;
active: boolean;
slaCriticalDays: number;
slaHighDays: number;
slaMediumDays: number;
slaLowDays: number;
};
RiskException
Self-declared with expiry + immutable audit log.
export type RiskException = SoftDeletableEntity & {
findingId: UUID;
reason: ExceptionReason;
justification: string;
declaredBy: string;
declaredAt: any;
expiresAt: any;
status: RiskExceptionStatus;
};
ComplianceControl
Per-framework rows linkable to findings.
export type ComplianceControl = SoftDeletableEntity & {
frameworkId: ComplianceFramework;
controlId: string;
title: string;
description: string;
};
AiChangeRiskSignal
Dedicated review queue entry for risk introduced by AI-generated
changes. Graduates into a SecurityFinding when confirmed.
export type AiChangeRiskSignal = SoftDeletableEntity & {
applicationId: UUID;
agentSessionId?: string;
signalType: AiSignalType;
severity: CanonicalSeverity;
summary: string;
evidence?: string;
state: AiSignalState;
ownerId?: UUID;
graduatedFindingId?: UUID;
discoveredAt: any;
resolvedAt?: any;
};
ASPM Value Objects
FindingFilter— typed filter reused by list / rank / campaign target.RiskScoreBreakdown— per-contribution risk score components.SLAWindow— calendar-day window per canonical severity.CVEReference,OwnershipPath— descriptive value objects.
ASPM Enums
CanonicalSeverity—Critical | High | Medium | Low | Info.FindingDomain—Code | Dependency | Secret | Container | Cloud | Api | Identity | Runtime | Compliance | Ai.FindingState—Open | Triaged | InProgress | Resolved | Closed | Exception.Exposure—Internet | Internal | Airgapped | Unknown.Criticality—Tier1 | Tier2 | Tier3.DataClassification—Public | Internal | Confidential | Restricted.ExceptionReason—FalsePositive | AcceptedRisk | CompensatingControl | NotApplicable | Other.RiskExceptionStatus—Active | Expired | Revoked.CampaignStatus—Draft | Active | Paused | Completed | Cancelled.SlaState—Healthy | AtRisk | Breached.AiSignalType—SecretInDiff | HighRiskDependencyAdded | LargeUnreviewedDiff | LicenseViolation | PromptInjectionShape | Other.AiSignalState—Open | Acknowledged | GraduatedToFinding | Dismissed | Resolved.ComplianceFramework—OwaspAsvs | CweTop25.
Maintaining This Document
Update when:
- Entity properties change in TypeSpec definitions (
tsp/) - New entities are added
- Value objects change
- Enums are added or modified
Source of truth: TypeSpec files in tsp/ directory. Generated TypeScript types in packages/core/src/domain/generated/output.ts.
Related docs:
- repository-interfaces.md - Persistence
- ../concepts/ - Conceptual explanations
- ../architecture/clean-architecture.md - Layer context