dsh-pentester 0.0.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +39 -5
  2. package/agents/impact/profile.yml +19 -0
  3. package/agents/recon/profile.yml +23 -0
  4. package/agents/reporting/REPORT_TEMPLATE.md +333 -0
  5. package/agents/reporting/profile.yml +45 -0
  6. package/agents/threat-model/profile.yml +19 -0
  7. package/agents/validation/profile.yml +20 -0
  8. package/agents/vulnerability/profile.yml +19 -0
  9. package/agents/web/profile.yml +19 -0
  10. package/cordis.dev.patch.yml +16 -0
  11. package/cordis.patch.yml +2 -0
  12. package/docker/README.md +60 -0
  13. package/docker/kali/Dockerfile +881 -0
  14. package/docker/kali/README.md +104 -0
  15. package/docker/kali/REPORT_TEMPLATE.md +333 -0
  16. package/docker/kali/TOOL_PROMPT.md +362 -0
  17. package/docker/kali/bin/clone-kb +39 -0
  18. package/docker/kali/bin/entrypoint.sh +9 -0
  19. package/docker/kali/bin/gen-tools-json.sh +246 -0
  20. package/docker/kali/bin/record-traffic.sh +32 -0
  21. package/docker/kali/bin/tool-info +31 -0
  22. package/docker/kali/bin/tool-list +17 -0
  23. package/lib/catalog-BmeOyr6n.js +231 -0
  24. package/lib/catalog-BmeOyr6n.js.map +1 -0
  25. package/lib/catalog-DhE_r18k.js +231 -0
  26. package/lib/catalog-DhE_r18k.js.map +1 -0
  27. package/lib/client.js +15234 -0
  28. package/lib/client.js.map +7 -0
  29. package/lib/container-listing-BI6Xj8l2.js +56 -0
  30. package/lib/container-listing-BI6Xj8l2.js.map +1 -0
  31. package/lib/container-listing-BWZoBnN_.js +56 -0
  32. package/lib/container-listing-BWZoBnN_.js.map +1 -0
  33. package/lib/container-listing-CE5t-Y_H.js +56 -0
  34. package/lib/container-listing-CE5t-Y_H.js.map +1 -0
  35. package/lib/container-listing-DZPBvrLD.js +56 -0
  36. package/lib/container-listing-DZPBvrLD.js.map +1 -0
  37. package/lib/docker-tar-_wf8UrSj.js +66 -0
  38. package/lib/docker-tar-_wf8UrSj.js.map +1 -0
  39. package/lib/engagement-container-store-B9D8g0wq.js +641 -0
  40. package/lib/engagement-container-store-B9D8g0wq.js.map +1 -0
  41. package/lib/engagement-container-store-Cf-h0B4F.js +641 -0
  42. package/lib/engagement-container-store-Cf-h0B4F.js.map +1 -0
  43. package/lib/engagement-container-store-Cu1wuur1.js +639 -0
  44. package/lib/engagement-container-store-Cu1wuur1.js.map +1 -0
  45. package/lib/engagement-container-store-L_Gms-zi.js +632 -0
  46. package/lib/engagement-container-store-L_Gms-zi.js.map +1 -0
  47. package/lib/index.d.ts +41 -0
  48. package/lib/index.js +3200 -0
  49. package/lib/index.js.map +1 -0
  50. package/lib/model-CZoiogVs.js +149 -0
  51. package/lib/model-CZoiogVs.js.map +1 -0
  52. package/lib/model-DKZ5Rjik.js +145 -0
  53. package/lib/model-DKZ5Rjik.js.map +1 -0
  54. package/lib/worker-events-jFvaBp9x.js +351 -0
  55. package/lib/worker-events-jFvaBp9x.js.map +1 -0
  56. package/lib/worker-events-juSf0EDW.js +347 -0
  57. package/lib/worker-events-juSf0EDW.js.map +1 -0
  58. package/package.json +89 -8
  59. package/presets/pentester/agent.cordis.yml +194 -0
  60. package/presets/pentester/preset.yml +2 -0
  61. package/presets/pentester/run-state.mjs +210 -0
  62. package/index.js +0 -5
@@ -0,0 +1,149 @@
1
+ //#region src/core/model.ts
2
+ function brand(value) {
3
+ return value;
4
+ }
5
+ const ASSET_ORIGINS = [
6
+ "initial-target",
7
+ "discovered",
8
+ "derived"
9
+ ];
10
+ const STAGE_STATUSES = [
11
+ "pending",
12
+ "active",
13
+ "completed",
14
+ "skipped"
15
+ ];
16
+ const STAGE_TRANSITION_REASONS = [
17
+ "workflow",
18
+ "manual_override",
19
+ "skip"
20
+ ];
21
+ const TASK_STATUSES = [
22
+ "pending",
23
+ "running",
24
+ "blocked",
25
+ "completed",
26
+ "failed",
27
+ "cancelled",
28
+ "interrupted"
29
+ ];
30
+ const ARTIFACT_KINDS = [
31
+ "asset",
32
+ "service",
33
+ "endpoint",
34
+ "technology",
35
+ "observation",
36
+ "attack-surface",
37
+ "attack-path",
38
+ "hypothesis",
39
+ "impact",
40
+ "other"
41
+ ];
42
+ const IDENTITY_STABLE_ARTIFACT_KINDS = [
43
+ "asset",
44
+ "service",
45
+ "endpoint",
46
+ "technology"
47
+ ];
48
+ const AGENT_RUN_STATUSES = [
49
+ "created",
50
+ "running",
51
+ "blocked",
52
+ "completed",
53
+ "failed",
54
+ "cancelled",
55
+ "interrupted"
56
+ ];
57
+ const EVIDENCE_KINDS = [
58
+ "http-request",
59
+ "http-response",
60
+ "screenshot",
61
+ "tool-output",
62
+ "file",
63
+ "raw-scanner-output",
64
+ "other"
65
+ ];
66
+ const FINDING_STATUSES = [
67
+ "candidate",
68
+ "validating",
69
+ "confirmed",
70
+ "unconfirmed",
71
+ "false_positive"
72
+ ];
73
+ const FINDING_SEVERITIES = [
74
+ "info",
75
+ "low",
76
+ "medium",
77
+ "high",
78
+ "critical"
79
+ ];
80
+ const DEFAULT_EVIDENCE_STORAGE_LIMITS = { maxEvidenceBytes: 8388608 };
81
+ const DEFAULT_TOOL_OUTPUT_LIMITS = {
82
+ maxInlineOutputBytes: 8192,
83
+ maxTotalCapturedBytes: 1048576
84
+ };
85
+ const DEFAULT_TOOL_BROKER_LIMITS = {
86
+ maxPerEngagement: 4,
87
+ maxPerAgentRun: 2
88
+ };
89
+ const PTES_STAGE_KINDS = [
90
+ "pre-engagement",
91
+ "intelligence-gathering",
92
+ "threat-modeling",
93
+ "vulnerability-analysis",
94
+ "exploitation",
95
+ "post-exploitation",
96
+ "reporting"
97
+ ];
98
+ const PTES_STAGE_DEFINITIONS = [
99
+ {
100
+ id: "pre-engagement",
101
+ name: "Pre-engagement",
102
+ order: 1,
103
+ description: "Authorize the assessment, record objectives, and establish Scope and initial Assets."
104
+ },
105
+ {
106
+ id: "intelligence-gathering",
107
+ name: "Intelligence Gathering",
108
+ order: 2,
109
+ description: "Discover Assets, services, endpoints, technologies, and observations inside Scope."
110
+ },
111
+ {
112
+ id: "threat-modeling",
113
+ name: "Threat Modeling",
114
+ order: 3,
115
+ description: "Turn known Assets and observations into attack surface, paths, priorities, and hypotheses."
116
+ },
117
+ {
118
+ id: "vulnerability-analysis",
119
+ name: "Vulnerability Analysis",
120
+ order: 4,
121
+ description: "Produce candidate Findings, Evidence, and validation Tasks from attack paths."
122
+ },
123
+ {
124
+ id: "exploitation",
125
+ name: "Exploitation",
126
+ order: 5,
127
+ description: "Validate candidate Findings into confirmed, unconfirmed, or false positive outcomes."
128
+ },
129
+ {
130
+ id: "post-exploitation",
131
+ name: "Post Exploitation",
132
+ order: 6,
133
+ description: "Assess impact, privileges, reachability, and updated attack paths."
134
+ },
135
+ {
136
+ id: "reporting",
137
+ name: "Reporting",
138
+ order: 7,
139
+ description: "Consume Scope, Artifacts, Evidence, Findings, and timeline into a Report."
140
+ }
141
+ ];
142
+ /** Exhaustiveness guard (never-fallthrough for union switches). */
143
+ function assertNever(value, message) {
144
+ throw new Error(message ?? `unhandled member: ${String(value)}`);
145
+ }
146
+ //#endregion
147
+ export { brand as _, DEFAULT_TOOL_BROKER_LIMITS as a, FINDING_SEVERITIES as c, PTES_STAGE_DEFINITIONS as d, PTES_STAGE_KINDS as f, assertNever as g, TASK_STATUSES as h, DEFAULT_EVIDENCE_STORAGE_LIMITS as i, FINDING_STATUSES as l, STAGE_TRANSITION_REASONS as m, ARTIFACT_KINDS as n, DEFAULT_TOOL_OUTPUT_LIMITS as o, STAGE_STATUSES as p, ASSET_ORIGINS as r, EVIDENCE_KINDS as s, AGENT_RUN_STATUSES as t, IDENTITY_STABLE_ARTIFACT_KINDS as u };
148
+
149
+ //# sourceMappingURL=model-CZoiogVs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-CZoiogVs.js","names":[],"sources":["../src/core/model.ts"],"sourcesContent":["/**\n * core/model.ts — consolidated module (Wave 5; see docs/refactor/wave-5-mapping.md).\n */\n// ── from src/domain/ids.ts ────────────────────────────────────────\nexport type EngagementId = string & { readonly __brand: 'EngagementId' }\nexport type TargetId = string & { readonly __brand: 'TargetId' }\nexport type AssetId = string & { readonly __brand: 'AssetId' }\nexport type ScopeId = string & { readonly __brand: 'ScopeId' }\nexport type StageId = string & { readonly __brand: 'StageId' }\nexport type TaskId = string & { readonly __brand: 'TaskId' }\nexport type AgentTemplateId = string & { readonly __brand: 'AgentTemplateId' }\nexport type AgentRunId = string & { readonly __brand: 'AgentRunId' }\nexport type SkillId = string & { readonly __brand: 'SkillId' }\nexport type McpServerId = string & { readonly __brand: 'McpServerId' }\nexport type ToolboxId = string & { readonly __brand: 'ToolboxId' }\nexport type ToolId = string & { readonly __brand: 'ToolId' }\nexport type ToolCallId = string & { readonly __brand: 'ToolCallId' }\nexport type ArtifactId = string & { readonly __brand: 'ArtifactId' }\nexport type EvidenceId = string & { readonly __brand: 'EvidenceId' }\nexport type FindingId = string & { readonly __brand: 'FindingId' }\nexport type FindingOccurrenceId = string & { readonly __brand: 'FindingOccurrenceId' }\ntype ReportId = string & { readonly __brand: 'ReportId' }\nexport type EventId = string & { readonly __brand: 'EventId' }\n\nexport function brand<T extends string>(value: string): T {\n return value as T\n}\n// ── from src/domain/asset.ts ────────────────────────────────────────\nexport const ASSET_ORIGINS = ['initial-target', 'discovered', 'derived'] as const\n\nexport type AssetOrigin = (typeof ASSET_ORIGINS)[number]\n\nexport interface Asset {\n readonly id: AssetId\n readonly engagementId: EngagementId\n readonly value: string\n readonly origin: AssetOrigin\n readonly sourceTargetId?: TargetId\n}\n// ── from src/domain/target.ts ────────────────────────────────────────\nexport interface Target {\n readonly id: TargetId\n readonly engagementId: EngagementId\n readonly value: string\n readonly initialAssetId: AssetId\n}\n// ── from src/domain/stage.ts ────────────────────────────────────────\nexport const STAGE_STATUSES = ['pending', 'active', 'completed', 'skipped'] as const\n\nexport type StageStatus = (typeof STAGE_STATUSES)[number]\n\nexport const STAGE_TRANSITION_REASONS = ['workflow', 'manual_override', 'skip'] as const\n\nexport type StageTransitionReason = (typeof STAGE_TRANSITION_REASONS)[number]\n\nexport interface Stage {\n readonly id: StageId\n readonly engagementId: EngagementId\n readonly kind: PtesStageKind\n readonly status: StageStatus\n /** P1-6: human-readable reason when the Stage was user-skipped. */\n readonly skippedReason?: string\n /** P1-6: ISO timestamp when the Stage was skipped. */\n readonly skippedAt?: string\n}\n// ── from src/domain/task.ts ────────────────────────────────────────\nexport const TASK_STATUSES = [\n 'pending',\n 'running',\n 'blocked',\n 'completed',\n 'failed',\n 'cancelled',\n 'interrupted',\n] as const\n\nexport type TaskStatus = (typeof TASK_STATUSES)[number]\n\nexport interface Task {\n readonly id: TaskId\n readonly engagementId: EngagementId\n readonly stageId: StageId\n readonly kind: PtesStageKind\n readonly goal: string\n readonly primaryAgentRunId: AgentRunId\n readonly dependsOn: readonly TaskId[]\n readonly status: TaskStatus\n readonly parentTaskId?: TaskId\n}\n// ── from src/domain/artifact.ts ────────────────────────────────────────\nexport const ARTIFACT_KINDS = [\n 'asset',\n 'service',\n 'endpoint',\n 'technology',\n 'observation',\n 'attack-surface',\n 'attack-path',\n 'hypothesis',\n 'impact',\n 'other',\n] as const\n\nexport type ArtifactKind = (typeof ARTIFACT_KINDS)[number]\n\nexport const IDENTITY_STABLE_ARTIFACT_KINDS = ['asset', 'service', 'endpoint', 'technology'] as const\ntype IdentityStableArtifactKind = (typeof IDENTITY_STABLE_ARTIFACT_KINDS)[number]\n\nexport interface ArtifactProvenance {\n readonly sourcePtapMessageId: string\n readonly createdInStageId: StageId\n readonly producedByTaskId: TaskId\n readonly producedByAgentRunId: AgentRunId\n readonly observedAt: string\n}\n\nexport interface ArtifactIdentityFields {\n readonly assetValue?: string\n readonly assetId?: string\n readonly protocol?: string\n readonly port?: number\n readonly serviceId?: string\n readonly method?: string\n readonly path?: string\n readonly ownerRef?: string\n readonly technologyName?: string\n}\n\nexport interface Artifact {\n readonly id: ArtifactId\n readonly engagementId: EngagementId\n readonly kind: ArtifactKind\n readonly createdInStageId: StageId\n readonly producedByTaskId: TaskId\n readonly producedByAgentRunId: AgentRunId\n readonly evidenceIds: readonly EvidenceId[]\n readonly summary: string\n readonly identityKey?: string\n readonly identity?: ArtifactIdentityFields\n readonly provenance: readonly ArtifactProvenance[]\n}\n\n/** Protocol-facing draft. PTES Core assigns `ArtifactId` on persist. */\nexport interface ArtifactSubmission extends ArtifactIdentityFields {\n readonly kind: ArtifactKind\n readonly summary: string\n readonly evidenceRefs?: readonly string[]\n}\n// ── from src/domain/agent.ts ────────────────────────────────────────\ntype AgentTemplateKind = 'built-in' | 'user'\n\nexport interface AgentTemplate {\n readonly id: AgentTemplateId\n readonly kind: AgentTemplateKind\n readonly name: string\n readonly description: string\n readonly rolePrompt: string\n readonly model?: string\n readonly skillIds: readonly SkillId[]\n readonly mcpServerIds: readonly McpServerId[]\n readonly allowedToolboxIds: readonly ToolboxId[]\n readonly attachedStages: readonly PtesStageKind[]\n}\n\nexport const AGENT_RUN_STATUSES = [\n 'created',\n 'running',\n 'blocked',\n 'completed',\n 'failed',\n 'cancelled',\n 'interrupted',\n] as const\n\nexport type AgentRunStatus = (typeof AGENT_RUN_STATUSES)[number]\n\n/**\n * Immutable configuration snapshot captured when an AgentRun is created.\n * A running Worker must never change mid-flight when Global Settings change:\n * instructions / skills / MCP / Docker image stay exactly as snapshotted.\n */\nexport interface AgentRunConfigSnapshot {\n readonly agentTemplateId: AgentTemplateId\n readonly agentTemplateRevision: number\n readonly agentName: string\n readonly instructions: string\n readonly skillIds: readonly SkillId[]\n readonly mcpServerIds: readonly McpServerId[]\n readonly allowedToolboxIds: readonly ToolboxId[]\n readonly primaryToolboxId?: ToolboxId\n}\n\nexport interface AgentRun {\n readonly id: AgentRunId\n readonly engagementId: EngagementId\n readonly templateId: AgentTemplateId\n readonly status: AgentRunStatus\n readonly taskIds: readonly TaskId[]\n readonly currentTaskId?: TaskId\n /** Immutable Global-config snapshot captured at creation (rev-stable). */\n readonly configSnapshot?: AgentRunConfigSnapshot\n}\n\ninterface DelegateRequest {\n readonly fromAgentRunId: AgentRunId\n readonly reason: string\n readonly suggestedTemplateId?: AgentTemplateId\n}\n// ── from src/domain/evidence.ts ────────────────────────────────────────\nexport const EVIDENCE_KINDS = [\n 'http-request',\n 'http-response',\n 'screenshot',\n 'tool-output',\n 'file',\n 'raw-scanner-output',\n 'other',\n] as const\n\nexport type EvidenceKind = (typeof EVIDENCE_KINDS)[number]\n\nexport interface Evidence {\n readonly id: EvidenceId\n readonly engagementId: EngagementId\n readonly kind: EvidenceKind\n readonly producedByTaskId?: TaskId\n readonly producedByAgentRunId?: AgentRunId\n readonly ref: string\n readonly summary: string\n readonly mediaType?: string\n readonly sizeBytes: number\n readonly sha256: string\n readonly createdInStageId: StageId\n readonly sourcePtapMessageId: string\n readonly createdAt: string\n}\n\n/** Protocol-facing draft. Small content may be inline; large content uses `ref`. */\nexport interface EvidenceSubmission {\n readonly kind: EvidenceKind\n readonly summary: string\n readonly content?: string\n readonly ref?: string\n readonly mediaType?: string\n}\n// ── from src/domain/finding.ts ────────────────────────────────────────\nexport const FINDING_STATUSES = [\n 'candidate',\n 'validating',\n 'confirmed',\n 'unconfirmed',\n 'false_positive',\n] as const\n\nexport type FindingStatus = (typeof FINDING_STATUSES)[number]\n\nexport const FINDING_SEVERITIES = ['info', 'low', 'medium', 'high', 'critical'] as const\n\nexport type FindingSeverity = (typeof FINDING_SEVERITIES)[number]\n\nexport interface Finding {\n readonly id: FindingId\n readonly engagementId: EngagementId\n readonly title: string\n readonly severity: FindingSeverity\n readonly confidence: number\n readonly status: FindingStatus\n readonly occurrenceIds: readonly FindingOccurrenceId[]\n readonly category?: string\n readonly weakness?: string\n readonly cwe?: string\n readonly identityKey?: string\n readonly createdInStageId?: StageId\n readonly producedByTaskId?: TaskId\n readonly producedByAgentRunId?: AgentRunId\n}\n\nexport interface FindingOccurrence {\n readonly id: FindingOccurrenceId\n readonly findingId: FindingId\n readonly engagementId: EngagementId\n readonly assetId: AssetId\n readonly endpoint?: string\n readonly serviceId?: string\n readonly evidenceIds: readonly EvidenceId[]\n readonly reproductionContext?: string\n readonly status: FindingStatus\n readonly identityKey?: string\n}\n\ninterface FindingOccurrenceSubmission {\n readonly assetId: string\n readonly endpoint?: string\n readonly serviceId?: string\n readonly evidenceRefs?: readonly string[]\n readonly reproductionContext?: string\n}\n\n/** Protocol-facing draft. PTES Core assigns `FindingId` on persist. */\nexport interface FindingSubmission {\n readonly title: string\n readonly severity: FindingSeverity\n readonly confidence: number\n readonly status: FindingStatus\n readonly summary?: string\n readonly category?: string\n readonly weakness?: string\n readonly cwe?: string\n readonly occurrence?: FindingOccurrenceSubmission\n}\n// ── from src/domain/ptes-core.ts ────────────────────────────────────────\nexport const PTES_CORE_INDEX_SCHEMA_VERSION = 1 as const\n\nexport type ArtifactRecord = Artifact\nexport type FindingRecord = Finding\nexport type FindingOccurrenceRecord = FindingOccurrence\n\nexport interface EvidenceRecord extends Evidence {\n readonly resourceRef: ContextResourceRef\n}\n\ntype ArtifactUpsertStatus = 'created' | 'merged'\ntype FindingUpsertStatus = 'created' | 'merged'\ntype OccurrenceUpsertStatus = 'created' | 'merged'\n\nexport interface ArtifactUpsertResult {\n readonly status: ArtifactUpsertStatus\n readonly artifact: ArtifactRecord\n}\n\nexport interface FindingUpsertResult {\n readonly status: FindingUpsertStatus\n readonly finding: FindingRecord\n}\n\nexport interface FindingOccurrenceUpsertResult {\n readonly status: OccurrenceUpsertStatus\n readonly occurrence: FindingOccurrenceRecord\n readonly finding: FindingRecord\n}\n\nexport type IngestionResult =\n | {\n readonly type: 'artifact'\n readonly artifactId: ArtifactId\n readonly status: ArtifactUpsertStatus\n }\n | {\n readonly type: 'evidence'\n readonly evidenceId: EvidenceId\n }\n | {\n readonly type: 'finding'\n readonly findingId: FindingId\n readonly occurrenceId?: FindingOccurrenceId\n readonly findingStatus: FindingUpsertStatus\n readonly occurrenceStatus?: OccurrenceUpsertStatus\n }\n\nexport interface ArtifactQuery {\n readonly kind?: Artifact['kind']\n readonly identityKey?: string\n}\n\nexport interface EvidenceQuery {\n readonly kind?: Evidence['kind']\n}\n\nexport interface FindingQuery {\n readonly status?: FindingStatus\n readonly identityKey?: string\n}\n\nexport interface EvidenceStorageLimits {\n readonly maxEvidenceBytes: number\n}\n\nexport const DEFAULT_EVIDENCE_STORAGE_LIMITS: EvidenceStorageLimits = {\n maxEvidenceBytes: 8 * 1024 * 1024,\n}\n\ninterface PtesCoreIndexMeta {\n readonly schemaVersion: typeof PTES_CORE_INDEX_SCHEMA_VERSION\n readonly lastEventSequence: number\n}\n\nexport interface ArtifactIndexSnapshot extends PtesCoreIndexMeta {\n readonly artifacts: Readonly<Record<string, ArtifactRecord>>\n readonly artifactIdsByIdentityKey: Readonly<Record<string, ArtifactId>>\n}\n\nexport interface EvidenceIndexSnapshot extends PtesCoreIndexMeta {\n readonly evidence: Readonly<Record<string, EvidenceRecord>>\n}\n\nexport interface FindingIndexSnapshot extends PtesCoreIndexMeta {\n readonly findings: Readonly<Record<string, FindingRecord>>\n readonly occurrences: Readonly<Record<string, FindingOccurrenceRecord>>\n readonly findingIdsByIdentityKey: Readonly<Record<string, FindingId>>\n readonly occurrenceIdsByIdentityKey: Readonly<Record<string, FindingOccurrenceId>>\n}\n\nexport interface IngestionIndexSnapshot extends PtesCoreIndexMeta {\n readonly results: Readonly<Record<string, IngestionResult>>\n}\n\nexport interface PtesCoreState {\n readonly schemaVersion: typeof PTES_CORE_INDEX_SCHEMA_VERSION\n readonly lastEventSequence: number\n readonly engagementId: EngagementId\n readonly artifacts: Readonly<Record<string, ArtifactRecord>>\n readonly artifactIdsByIdentityKey: Readonly<Record<string, ArtifactId>>\n readonly evidence: Readonly<Record<string, EvidenceRecord>>\n readonly findings: Readonly<Record<string, FindingRecord>>\n readonly occurrences: Readonly<Record<string, FindingOccurrenceRecord>>\n readonly findingIdsByIdentityKey: Readonly<Record<string, FindingId>>\n readonly occurrenceIdsByIdentityKey: Readonly<Record<string, FindingOccurrenceId>>\n readonly ingestion: Readonly<Record<string, IngestionResult>>\n}\n// ── from src/domain/tools.ts ────────────────────────────────────────\nconst TOOL_CALL_STATUSES = [\n 'requested',\n 'pending_approval',\n 'queued',\n 'running',\n 'succeeded',\n 'failed',\n 'timed_out',\n 'cancelled',\n 'interrupted',\n 'denied',\n 'capability_required',\n] as const\n\nexport type ToolCallStatus = (typeof TOOL_CALL_STATUSES)[number]\n\nconst TOOL_RISK_DECISIONS = ['AUTO', 'APPROVAL', 'DENY'] as const\nexport type ToolRiskDecision = (typeof TOOL_RISK_DECISIONS)[number]\n\nconst TOOL_OPERATION_CLASSES = [\n 'sandbox_setup',\n 'recon',\n 'read_only_validation',\n 'target_state_change',\n 'high_risk',\n 'escape',\n] as const\nexport type ToolOperationClass = (typeof TOOL_OPERATION_CLASSES)[number]\n\nconst TOOL_FAILURE_KINDS = [\n 'timeout',\n 'transport',\n 'execution',\n 'backend_unavailable',\n 'toolbox_image_unavailable',\n 'cancelled',\n 'invalid_result',\n 'unknown',\n] as const\nexport type ToolFailureKind = (typeof TOOL_FAILURE_KINDS)[number]\n\nconst TOOLBOX_LIFECYCLES = ['agent_run', 'engagement'] as const\ntype ToolboxLifecycle = (typeof TOOLBOX_LIFECYCLES)[number]\n\nconst MCP_LIFECYCLES = ['agent_run', 'engagement'] as const\nexport type McpLifecycle = (typeof MCP_LIFECYCLES)[number]\n\nconst DOCKER_RUNTIME_STATUSES = ['running', 'stopped', 'missing', 'unhealthy', 'unknown'] as const\ntype DockerRuntimeStatus = (typeof DOCKER_RUNTIME_STATUSES)[number]\n\nconst MCP_RUNTIME_STATUSES = ['connected', 'reconnectable', 'stopped', 'unavailable', 'unknown'] as const\ntype McpRuntimeStatus = (typeof MCP_RUNTIME_STATUSES)[number]\n\nconst IMAGE_RESOLVE_SOURCES = ['existing', 'built', 'pulled'] as const\nexport type ImageResolveSource = (typeof IMAGE_RESOLVE_SOURCES)[number]\n\nconst TOOL_RETRY_HINTS = ['transient', 'permanent', 'unknown'] as const\nexport type ToolRetryHint = (typeof TOOL_RETRY_HINTS)[number]\n\nconst TOOL_TERMINATIONS = ['confirmed', 'requested', 'unknown'] as const\nexport type ToolTermination = (typeof TOOL_TERMINATIONS)[number]\n\ntype ToolBackendBinding =\n | { readonly kind: 'docker'; readonly executor: string }\n | { readonly kind: 'mcp'; readonly serverId: McpServerId; readonly remoteToolName: string }\n\ninterface ToolTimeoutSpec {\n readonly defaultMs: number\n readonly maxMs: number\n}\n\nexport interface ToolScopeTarget {\n readonly value: string\n}\n\nexport interface ToolCallRequest {\n readonly engagementId: EngagementId\n readonly taskId: TaskId\n readonly agentRunId: AgentRunId\n readonly toolId: ToolId\n readonly arguments: unknown\n readonly timeoutMs?: number\n readonly retryOf?: ToolCallId\n}\n\nexport interface ToolDefinition {\n readonly id: ToolId\n readonly name: string\n readonly description: string\n readonly toolboxId: ToolboxId\n readonly backend: ToolBackendBinding\n readonly risk: ToolRiskDecision\n readonly timeout: ToolTimeoutSpec\n readonly requiredArgumentKeys?: readonly string[]\n readonly scopeTargets?: (args: Record<string, unknown>) => readonly ToolScopeTarget[]\n}\n\ninterface ToolboxProvisioning {\n readonly dockerfile?: {\n readonly context: string\n readonly dockerfile: string\n }\n readonly pull?: {\n readonly image: string\n }\n}\n\nexport interface ToolboxDefinition {\n readonly id: ToolboxId\n readonly name: string\n readonly description: string\n readonly toolIds: readonly ToolId[]\n readonly image: string\n readonly lifecycle: ToolboxLifecycle\n readonly provisioning?: ToolboxProvisioning\n readonly env?: Readonly<Record<string, string>>\n readonly secrets?: Readonly<Record<string, string>>\n}\n\ntype ContainerExecSpec =\n | {\n readonly mode: 'argv'\n readonly toolboxId: ToolboxId\n readonly executable: string\n readonly args?: readonly string[]\n readonly cwd?: string\n readonly env?: Readonly<Record<string, string>>\n readonly timeoutMs?: number\n readonly operationClass?: ToolOperationClass\n readonly declaredTargets?: readonly ToolScopeTarget[]\n }\n | {\n readonly mode: 'shell'\n readonly toolboxId: ToolboxId\n readonly command: string\n readonly cwd?: string\n readonly env?: Readonly<Record<string, string>>\n readonly timeoutMs?: number\n readonly operationClass?: ToolOperationClass\n readonly declaredTargets?: readonly ToolScopeTarget[]\n }\n\n/** @deprecated Prefer ContainerExecSpec; kept as the parsed argv-shaped view. */\nexport interface ContainerExecArguments {\n readonly toolboxId: ToolboxId\n readonly mode: 'argv' | 'shell'\n readonly command: string\n readonly executable?: string\n readonly args?: readonly string[]\n readonly cwd?: string\n readonly env?: Readonly<Record<string, string>>\n readonly timeoutMs?: number\n readonly operationClass?: ToolOperationClass\n readonly declaredTargets?: readonly ToolScopeTarget[]\n}\n\nexport interface ToolOutputLimits {\n readonly maxInlineOutputBytes: number\n readonly maxTotalCapturedBytes: number\n}\n\nexport const DEFAULT_TOOL_OUTPUT_LIMITS: ToolOutputLimits = {\n maxInlineOutputBytes: 8_192,\n maxTotalCapturedBytes: 1_048_576,\n}\n\nexport interface DockerToolboxBinding {\n readonly engagementId: EngagementId\n readonly agentRunId?: AgentRunId\n readonly toolboxId: ToolboxId\n readonly lifecycle: ToolboxLifecycle\n readonly containerId: string\n readonly image: string\n readonly imageId?: string\n readonly imageSource?: ImageResolveSource\n}\n\ninterface McpTransportDefinition {\n readonly kind: 'fixture' | 'stdio' | 'http'\n readonly command?: string\n readonly args?: readonly string[]\n readonly url?: string\n}\n\ninterface McpServerConfig {\n readonly env?: Readonly<Record<string, string>>\n readonly secrets?: Readonly<Record<string, string>>\n}\n\nexport interface McpServerDefinition {\n readonly id: McpServerId\n readonly name: string\n readonly lifecycle: McpLifecycle\n readonly transport: McpTransportDefinition\n readonly config: McpServerConfig\n}\n\nexport interface McpRuntimeBinding {\n readonly engagementId: EngagementId\n readonly agentRunId?: AgentRunId\n readonly serverId: McpServerId\n readonly lifecycle: McpLifecycle\n readonly runtimeId?: string\n}\n\nexport interface ToolOutputResourceRef extends ContextResourceRef {}\n\nexport interface ToolCallRecord {\n readonly toolCallId: ToolCallId\n readonly request: ToolCallRequest\n readonly status: ToolCallStatus\n readonly createdAt: string\n readonly updatedAt: string\n readonly retryOf?: ToolCallId\n readonly reason?: string\n readonly outputRefs?: readonly ToolOutputResourceRef[]\n readonly retryHint?: ToolRetryHint\n readonly failureKind?: ToolFailureKind\n readonly termination?: ToolTermination\n readonly policySnapshot?: {\n readonly risk?: ToolRiskDecision\n readonly scope?: 'allowed' | 'denied'\n }\n}\n\nexport interface PendingToolCall {\n readonly toolCallId: ToolCallId\n readonly request: ToolCallRequest\n readonly status: 'pending_approval'\n readonly requestedAt: string\n readonly policySnapshot: {\n readonly risk: 'APPROVAL'\n readonly scope: 'allowed'\n readonly toolboxId: ToolboxId\n }\n}\n\nexport interface ToolBrokerConcurrencyLimits {\n readonly maxPerEngagement: number\n readonly maxPerAgentRun: number\n}\n\nexport const DEFAULT_TOOL_BROKER_LIMITS: ToolBrokerConcurrencyLimits = {\n maxPerEngagement: 4,\n maxPerAgentRun: 2,\n}\n// ── from src/domain/context.ts ────────────────────────────────────────\nconst CONTEXT_TRUST_LEVELS = [\n 'system',\n 'user',\n 'trusted_internal',\n 'untrusted_external',\n] as const\nexport type ContextTrustLevel = (typeof CONTEXT_TRUST_LEVELS)[number]\n\nconst CONTEXT_SOURCE_TYPES = [\n 'engagement',\n 'task',\n 'agent_run',\n 'asset',\n 'artifact',\n 'evidence',\n 'finding',\n 'user',\n] as const\ntype ContextSourceType = (typeof CONTEXT_SOURCE_TYPES)[number]\n\nconst CONTEXT_ITEM_KINDS = [\n 'asset',\n 'artifact',\n 'finding',\n 'evidence',\n 'related_task',\n 'guidance',\n] as const\nexport type ContextItemKind = (typeof CONTEXT_ITEM_KINDS)[number]\n\nexport type ContextPriority = 1 | 2 | 3 | 4 | 5 | 6\n\nexport interface ContextSource {\n readonly type: ContextSourceType\n readonly sourceId?: string\n readonly producedByTaskId?: TaskId\n readonly producedByAgentRunId?: AgentRunId\n readonly createdInStageId?: StageId\n readonly contentKind?: string\n}\n\nexport interface ContextResourceRef {\n readonly resourceId: string\n readonly kind: string\n readonly mediaType?: string\n readonly sizeBytes?: number\n}\n\ninterface InlineContextContent {\n readonly text: string\n readonly mediaType?: string\n}\n\ninterface ContextItemBase {\n readonly id: string\n readonly kind: ContextItemKind\n readonly trust: ContextTrustLevel\n readonly source: ContextSource\n readonly summary?: string\n readonly content?: InlineContextContent\n readonly ref?: ContextResourceRef\n readonly priority: ContextPriority\n}\n\ntype AssetContextItem = ContextItemBase & { readonly kind: 'asset' }\ntype ArtifactContextItem = ContextItemBase & { readonly kind: 'artifact' }\ntype FindingContextItem = ContextItemBase & { readonly kind: 'finding' }\ntype EvidenceContextItem = ContextItemBase & { readonly kind: 'evidence' }\ntype RelatedTaskContextItem = ContextItemBase & { readonly kind: 'related_task' }\ntype UserGuidanceContextItem = ContextItemBase & { readonly kind: 'guidance' }\n\nexport type ContextItem =\n | AssetContextItem\n | ArtifactContextItem\n | FindingContextItem\n | EvidenceContextItem\n | RelatedTaskContextItem\n | UserGuidanceContextItem\n\nexport interface ContextConstraint {\n readonly id: string\n readonly text: string\n}\n\ninterface EngagementContext {\n readonly id: EngagementId\n readonly objectives: string\n}\n\ninterface ScopeContext {\n readonly id: string\n readonly summary: string\n}\n\ninterface RoeContext {\n readonly summary: string\n}\n\ninterface StageContext {\n readonly id: StageId\n readonly kind: PtesStageKind\n readonly status: string\n}\n\ninterface TaskContext {\n readonly id: TaskId\n readonly goal: string\n readonly status: string\n readonly stageId: StageId\n readonly parentTaskId?: TaskId\n}\n\ninterface AgentTemplateContext {\n readonly id: AgentTemplateId\n readonly name: string\n readonly role: string\n /**\n * POLICY METADATA ONLY — never rendered as \"available tools\". The actual\n * model-facing tools come from the Worker Tool Manifest (resolveWorkerTools).\n */\n readonly capabilities: readonly string[]\n}\n\ninterface TaskLineageContext {\n readonly parentTaskId?: TaskId\n readonly parentSummary?: string\n}\n\ninterface ContextBundleMetadata {\n readonly builtAt: string\n readonly itemCount: number\n}\n\ninterface ContextDeltaMetadata {\n readonly builtAt: string\n readonly addedCount: number\n}\n\nexport interface TaskContextBundle {\n readonly engagement: EngagementContext\n readonly scope: ScopeContext\n readonly roe: RoeContext\n readonly stage: StageContext\n readonly task: TaskContext\n readonly agentTemplate: AgentTemplateContext\n readonly lineage: TaskLineageContext\n readonly assets: readonly AssetContextItem[]\n readonly artifacts: readonly ArtifactContextItem[]\n readonly findings: readonly FindingContextItem[]\n readonly evidence: readonly EvidenceContextItem[]\n readonly relatedTasks: readonly RelatedTaskContextItem[]\n readonly userGuidance: readonly UserGuidanceContextItem[]\n readonly constraints: readonly ContextConstraint[]\n readonly metadata: ContextBundleMetadata\n}\n\nexport interface TaskContextDelta {\n readonly task: TaskContext\n readonly addedItems: readonly ContextItem[]\n readonly addedRefs: readonly ContextResourceRef[]\n readonly userGuidance: readonly UserGuidanceContextItem[]\n readonly changedConstraints: readonly ContextConstraint[]\n readonly metadata: ContextDeltaMetadata\n}\n\nexport interface ContextBudget {\n readonly maxAssets: number\n readonly maxArtifacts: number\n readonly maxFindings: number\n readonly maxEvidenceRefs: number\n readonly maxRelatedTasks: number\n readonly maxUserGuidance: number\n readonly maxContextItems: number\n readonly maxEstimatedChars: number\n readonly maxInlineChars: number\n readonly maxMandatoryChars: number\n}\n\nexport interface ExplicitContextRef {\n readonly id: string\n readonly required?: boolean\n}\n\nexport interface ContextDeliveryState {\n readonly agentRunId: AgentRunId\n readonly deliveredItemIds: readonly string[]\n readonly deliveredRefIds: readonly string[]\n readonly revision: number\n readonly constraintFingerprint?: string\n}\n\nconst CONTEXT_BUILD_ERROR_CODES = [\n 'context_state_invalid',\n 'task_not_found',\n 'agent_run_not_found',\n 'template_not_found',\n 'scope_missing',\n 'unresolved_required_ref',\n 'mandatory_context_too_large',\n 'delivery_state_invalid',\n 'provider_failure',\n] as const\n\nexport type ContextBuildErrorCode = (typeof CONTEXT_BUILD_ERROR_CODES)[number]\n\n// ── PTES stage constants (Wave 5: moved from workflow to break the\n// engagement-store ↔ workflow import cycle) ──\nexport const PTES_STAGE_KINDS = [\n 'pre-engagement',\n 'intelligence-gathering',\n 'threat-modeling',\n 'vulnerability-analysis',\n 'exploitation',\n 'post-exploitation',\n 'reporting',\n] as const\n\nexport type PtesStageKind = (typeof PTES_STAGE_KINDS)[number]\n\n// ── from src/domain/workflow/stage-definition.ts ────────────────────────────────────────\nexport interface StageDefinition {\n readonly id: PtesStageKind\n readonly name: string\n readonly order: number\n readonly description: string\n}\n\nexport const PTES_STAGE_DEFINITIONS: readonly StageDefinition[] = [\n {\n id: 'pre-engagement',\n name: 'Pre-engagement',\n order: 1,\n description: 'Authorize the assessment, record objectives, and establish Scope and initial Assets.',\n },\n {\n id: 'intelligence-gathering',\n name: 'Intelligence Gathering',\n order: 2,\n description: 'Discover Assets, services, endpoints, technologies, and observations inside Scope.',\n },\n {\n id: 'threat-modeling',\n name: 'Threat Modeling',\n order: 3,\n description: 'Turn known Assets and observations into attack surface, paths, priorities, and hypotheses.',\n },\n {\n id: 'vulnerability-analysis',\n name: 'Vulnerability Analysis',\n order: 4,\n description: 'Produce candidate Findings, Evidence, and validation Tasks from attack paths.',\n },\n {\n id: 'exploitation',\n name: 'Exploitation',\n order: 5,\n description: 'Validate candidate Findings into confirmed, unconfirmed, or false positive outcomes.',\n },\n {\n id: 'post-exploitation',\n name: 'Post Exploitation',\n order: 6,\n description: 'Assess impact, privileges, reachability, and updated attack paths.',\n },\n {\n id: 'reporting',\n name: 'Reporting',\n order: 7,\n description: 'Consume Scope, Artifacts, Evidence, Findings, and timeline into a Report.',\n },\n]\n\n/** Exhaustiveness guard (never-fallthrough for union switches). */\nexport function assertNever(value: never, message?: string): never {\n throw new Error(message ?? `unhandled member: ${String(value)}`)\n}\n"],"mappings":";AAwBA,SAAgB,MAAwB,OAAkB;CACxD,OAAO;AACT;AAEA,MAAa,gBAAgB;CAAC;CAAkB;CAAc;AAAS;AAmBvE,MAAa,iBAAiB;CAAC;CAAW;CAAU;CAAa;AAAS;AAI1E,MAAa,2BAA2B;CAAC;CAAY;CAAmB;AAAM;AAe9E,MAAa,gBAAgB;CAC3B;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAgBA,MAAa,iBAAiB;CAC5B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAIA,MAAa,iCAAiC;CAAC;CAAS;CAAW;CAAY;AAAY;AA2D3F,MAAa,qBAAqB;CAChC;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAqCA,MAAa,iBAAiB;CAC5B;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AA6BA,MAAa,mBAAmB;CAC9B;CACA;CACA;CACA;CACA;AACF;AAIA,MAAa,qBAAqB;CAAC;CAAQ;CAAO;CAAU;CAAQ;AAAU;AAyH9E,MAAa,kCAAyD,EACpE,kBAAkB,QACpB;AA0MA,MAAa,6BAA+C;CAC1D,sBAAsB;CACtB,uBAAuB;AACzB;AA8EA,MAAa,6BAA0D;CACrE,kBAAkB;CAClB,gBAAgB;AAClB;AAiNA,MAAa,mBAAmB;CAC9B;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAYA,MAAa,yBAAqD;CAChE;EACE,IAAI;EACJ,MAAM;EACN,OAAO;EACP,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,OAAO;EACP,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,OAAO;EACP,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,OAAO;EACP,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,OAAO;EACP,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,OAAO;EACP,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,OAAO;EACP,aAAa;CACf;AACF;;AAGA,SAAgB,YAAY,OAAc,SAAyB;CACjE,MAAM,IAAI,MAAM,WAAW,qBAAqB,OAAO,KAAK,GAAG;AACjE"}
@@ -0,0 +1,145 @@
1
+ //#region src/core/model.ts
2
+ function brand(value) {
3
+ return value;
4
+ }
5
+ const ASSET_ORIGINS = [
6
+ "initial-target",
7
+ "discovered",
8
+ "derived"
9
+ ];
10
+ const STAGE_STATUSES = [
11
+ "pending",
12
+ "active",
13
+ "completed",
14
+ "skipped"
15
+ ];
16
+ const STAGE_TRANSITION_REASONS = [
17
+ "workflow",
18
+ "manual_override",
19
+ "skip"
20
+ ];
21
+ const TASK_STATUSES = [
22
+ "pending",
23
+ "running",
24
+ "blocked",
25
+ "completed",
26
+ "failed",
27
+ "cancelled",
28
+ "interrupted"
29
+ ];
30
+ const ARTIFACT_KINDS = [
31
+ "asset",
32
+ "service",
33
+ "endpoint",
34
+ "technology",
35
+ "observation",
36
+ "attack-surface",
37
+ "attack-path",
38
+ "hypothesis",
39
+ "impact",
40
+ "other"
41
+ ];
42
+ const IDENTITY_STABLE_ARTIFACT_KINDS = [
43
+ "asset",
44
+ "service",
45
+ "endpoint",
46
+ "technology"
47
+ ];
48
+ const AGENT_RUN_STATUSES = [
49
+ "created",
50
+ "running",
51
+ "blocked",
52
+ "completed",
53
+ "failed",
54
+ "cancelled",
55
+ "interrupted"
56
+ ];
57
+ const EVIDENCE_KINDS = [
58
+ "http-request",
59
+ "http-response",
60
+ "screenshot",
61
+ "tool-output",
62
+ "file",
63
+ "raw-scanner-output",
64
+ "other"
65
+ ];
66
+ const FINDING_STATUSES = [
67
+ "candidate",
68
+ "validating",
69
+ "confirmed",
70
+ "unconfirmed",
71
+ "false_positive"
72
+ ];
73
+ const FINDING_SEVERITIES = [
74
+ "info",
75
+ "low",
76
+ "medium",
77
+ "high",
78
+ "critical"
79
+ ];
80
+ const DEFAULT_EVIDENCE_STORAGE_LIMITS = { maxEvidenceBytes: 8388608 };
81
+ const DEFAULT_TOOL_OUTPUT_LIMITS = {
82
+ maxInlineOutputBytes: 8192,
83
+ maxTotalCapturedBytes: 1048576
84
+ };
85
+ const DEFAULT_TOOL_BROKER_LIMITS = {
86
+ maxPerEngagement: 4,
87
+ maxPerAgentRun: 2
88
+ };
89
+ const PTES_STAGE_KINDS = [
90
+ "pre-engagement",
91
+ "intelligence-gathering",
92
+ "threat-modeling",
93
+ "vulnerability-analysis",
94
+ "exploitation",
95
+ "post-exploitation",
96
+ "reporting"
97
+ ];
98
+ const PTES_STAGE_DEFINITIONS = [
99
+ {
100
+ id: "pre-engagement",
101
+ name: "Pre-engagement",
102
+ order: 1,
103
+ description: "Authorize the assessment, record objectives, and establish Scope and initial Assets."
104
+ },
105
+ {
106
+ id: "intelligence-gathering",
107
+ name: "Intelligence Gathering",
108
+ order: 2,
109
+ description: "Discover Assets, services, endpoints, technologies, and observations inside Scope."
110
+ },
111
+ {
112
+ id: "threat-modeling",
113
+ name: "Threat Modeling",
114
+ order: 3,
115
+ description: "Turn known Assets and observations into attack surface, paths, priorities, and hypotheses."
116
+ },
117
+ {
118
+ id: "vulnerability-analysis",
119
+ name: "Vulnerability Analysis",
120
+ order: 4,
121
+ description: "Produce candidate Findings, Evidence, and validation Tasks from attack paths."
122
+ },
123
+ {
124
+ id: "exploitation",
125
+ name: "Exploitation",
126
+ order: 5,
127
+ description: "Validate candidate Findings into confirmed, unconfirmed, or false positive outcomes."
128
+ },
129
+ {
130
+ id: "post-exploitation",
131
+ name: "Post Exploitation",
132
+ order: 6,
133
+ description: "Assess impact, privileges, reachability, and updated attack paths."
134
+ },
135
+ {
136
+ id: "reporting",
137
+ name: "Reporting",
138
+ order: 7,
139
+ description: "Consume Scope, Artifacts, Evidence, Findings, and timeline into a Report."
140
+ }
141
+ ];
142
+ //#endregion
143
+ export { DEFAULT_TOOL_BROKER_LIMITS as a, FINDING_SEVERITIES as c, PTES_STAGE_DEFINITIONS as d, PTES_STAGE_KINDS as f, brand as g, TASK_STATUSES as h, DEFAULT_EVIDENCE_STORAGE_LIMITS as i, FINDING_STATUSES as l, STAGE_TRANSITION_REASONS as m, ARTIFACT_KINDS as n, DEFAULT_TOOL_OUTPUT_LIMITS as o, STAGE_STATUSES as p, ASSET_ORIGINS as r, EVIDENCE_KINDS as s, AGENT_RUN_STATUSES as t, IDENTITY_STABLE_ARTIFACT_KINDS as u };
144
+
145
+ //# sourceMappingURL=model-DKZ5Rjik.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-DKZ5Rjik.js","names":[],"sources":["../src/core/model.ts"],"sourcesContent":["/**\n * core/model.ts — consolidated module (Wave 5; see docs/refactor/wave-5-mapping.md).\n */\n// ── from src/domain/ids.ts ────────────────────────────────────────\nexport type EngagementId = string & { readonly __brand: 'EngagementId' }\nexport type TargetId = string & { readonly __brand: 'TargetId' }\nexport type AssetId = string & { readonly __brand: 'AssetId' }\nexport type ScopeId = string & { readonly __brand: 'ScopeId' }\nexport type StageId = string & { readonly __brand: 'StageId' }\nexport type TaskId = string & { readonly __brand: 'TaskId' }\nexport type AgentTemplateId = string & { readonly __brand: 'AgentTemplateId' }\nexport type AgentRunId = string & { readonly __brand: 'AgentRunId' }\nexport type SkillId = string & { readonly __brand: 'SkillId' }\nexport type McpServerId = string & { readonly __brand: 'McpServerId' }\nexport type ToolboxId = string & { readonly __brand: 'ToolboxId' }\nexport type ToolId = string & { readonly __brand: 'ToolId' }\nexport type ToolCallId = string & { readonly __brand: 'ToolCallId' }\nexport type ArtifactId = string & { readonly __brand: 'ArtifactId' }\nexport type EvidenceId = string & { readonly __brand: 'EvidenceId' }\nexport type FindingId = string & { readonly __brand: 'FindingId' }\nexport type FindingOccurrenceId = string & { readonly __brand: 'FindingOccurrenceId' }\nexport type ReportId = string & { readonly __brand: 'ReportId' }\nexport type EventId = string & { readonly __brand: 'EventId' }\n\nexport function brand<T extends string>(value: string): T {\n return value as T\n}\n// ── from src/domain/asset.ts ────────────────────────────────────────\nexport const ASSET_ORIGINS = ['initial-target', 'discovered', 'derived'] as const\n\nexport type AssetOrigin = (typeof ASSET_ORIGINS)[number]\n\nexport interface Asset {\n readonly id: AssetId\n readonly engagementId: EngagementId\n readonly value: string\n readonly origin: AssetOrigin\n readonly sourceTargetId?: TargetId\n}\n// ── from src/domain/target.ts ────────────────────────────────────────\nexport interface Target {\n readonly id: TargetId\n readonly engagementId: EngagementId\n readonly value: string\n readonly initialAssetId: AssetId\n}\n// ── from src/domain/stage.ts ────────────────────────────────────────\nexport const STAGE_STATUSES = ['pending', 'active', 'completed', 'skipped'] as const\n\nexport type StageStatus = (typeof STAGE_STATUSES)[number]\n\nexport const STAGE_TRANSITION_REASONS = ['workflow', 'manual_override', 'skip'] as const\n\nexport type StageTransitionReason = (typeof STAGE_TRANSITION_REASONS)[number]\n\nexport interface Stage {\n readonly id: StageId\n readonly engagementId: EngagementId\n readonly kind: PtesStageKind\n readonly status: StageStatus\n /** P1-6: human-readable reason when the Stage was user-skipped. */\n readonly skippedReason?: string\n /** P1-6: ISO timestamp when the Stage was skipped. */\n readonly skippedAt?: string\n}\n// ── from src/domain/task.ts ────────────────────────────────────────\nexport const TASK_STATUSES = [\n 'pending',\n 'running',\n 'blocked',\n 'completed',\n 'failed',\n 'cancelled',\n 'interrupted',\n] as const\n\nexport type TaskStatus = (typeof TASK_STATUSES)[number]\n\nexport interface Task {\n readonly id: TaskId\n readonly engagementId: EngagementId\n readonly stageId: StageId\n readonly kind: PtesStageKind\n readonly goal: string\n readonly primaryAgentRunId: AgentRunId\n readonly dependsOn: readonly TaskId[]\n readonly status: TaskStatus\n readonly parentTaskId?: TaskId\n}\n// ── from src/domain/artifact.ts ────────────────────────────────────────\nexport const ARTIFACT_KINDS = [\n 'asset',\n 'service',\n 'endpoint',\n 'technology',\n 'observation',\n 'attack-surface',\n 'attack-path',\n 'hypothesis',\n 'impact',\n 'other',\n] as const\n\nexport type ArtifactKind = (typeof ARTIFACT_KINDS)[number]\n\nexport const IDENTITY_STABLE_ARTIFACT_KINDS = ['asset', 'service', 'endpoint', 'technology'] as const\nexport type IdentityStableArtifactKind = (typeof IDENTITY_STABLE_ARTIFACT_KINDS)[number]\n\nexport interface ArtifactProvenance {\n readonly sourcePtapMessageId: string\n readonly createdInStageId: StageId\n readonly producedByTaskId: TaskId\n readonly producedByAgentRunId: AgentRunId\n readonly observedAt: string\n}\n\nexport interface ArtifactIdentityFields {\n readonly assetValue?: string\n readonly assetId?: string\n readonly protocol?: string\n readonly port?: number\n readonly serviceId?: string\n readonly method?: string\n readonly path?: string\n readonly ownerRef?: string\n readonly technologyName?: string\n}\n\nexport interface Artifact {\n readonly id: ArtifactId\n readonly engagementId: EngagementId\n readonly kind: ArtifactKind\n readonly createdInStageId: StageId\n readonly producedByTaskId: TaskId\n readonly producedByAgentRunId: AgentRunId\n readonly evidenceIds: readonly EvidenceId[]\n readonly summary: string\n readonly identityKey?: string\n readonly identity?: ArtifactIdentityFields\n readonly provenance: readonly ArtifactProvenance[]\n}\n\n/** Protocol-facing draft. PTES Core assigns `ArtifactId` on persist. */\nexport interface ArtifactSubmission extends ArtifactIdentityFields {\n readonly kind: ArtifactKind\n readonly summary: string\n readonly evidenceRefs?: readonly string[]\n}\n// ── from src/domain/agent.ts ────────────────────────────────────────\nexport type AgentTemplateKind = 'built-in' | 'user'\n\nexport interface AgentTemplate {\n readonly id: AgentTemplateId\n readonly kind: AgentTemplateKind\n readonly name: string\n readonly description: string\n readonly rolePrompt: string\n readonly model?: string\n readonly skillIds: readonly SkillId[]\n readonly mcpServerIds: readonly McpServerId[]\n readonly allowedToolboxIds: readonly ToolboxId[]\n readonly attachedStages: readonly PtesStageKind[]\n}\n\nexport const AGENT_RUN_STATUSES = [\n 'created',\n 'running',\n 'blocked',\n 'completed',\n 'failed',\n 'cancelled',\n 'interrupted',\n] as const\n\nexport type AgentRunStatus = (typeof AGENT_RUN_STATUSES)[number]\n\n/**\n * Immutable configuration snapshot captured when an AgentRun is created.\n * A running Worker must never change mid-flight when Global Settings change:\n * instructions / skills / MCP / Docker image stay exactly as snapshotted.\n */\nexport interface AgentRunConfigSnapshot {\n readonly agentTemplateId: AgentTemplateId\n readonly agentTemplateRevision: number\n readonly agentName: string\n readonly instructions: string\n readonly skillIds: readonly SkillId[]\n readonly mcpServerIds: readonly McpServerId[]\n readonly allowedToolboxIds: readonly ToolboxId[]\n readonly primaryToolboxId?: ToolboxId\n}\n\nexport interface AgentRun {\n readonly id: AgentRunId\n readonly engagementId: EngagementId\n readonly templateId: AgentTemplateId\n readonly status: AgentRunStatus\n readonly taskIds: readonly TaskId[]\n readonly currentTaskId?: TaskId\n /** Immutable Global-config snapshot captured at creation (rev-stable). */\n readonly configSnapshot?: AgentRunConfigSnapshot\n}\n\nexport interface DelegateRequest {\n readonly fromAgentRunId: AgentRunId\n readonly reason: string\n readonly suggestedTemplateId?: AgentTemplateId\n}\n// ── from src/domain/evidence.ts ────────────────────────────────────────\nexport const EVIDENCE_KINDS = [\n 'http-request',\n 'http-response',\n 'screenshot',\n 'tool-output',\n 'file',\n 'raw-scanner-output',\n 'other',\n] as const\n\nexport type EvidenceKind = (typeof EVIDENCE_KINDS)[number]\n\nexport interface Evidence {\n readonly id: EvidenceId\n readonly engagementId: EngagementId\n readonly kind: EvidenceKind\n readonly producedByTaskId?: TaskId\n readonly producedByAgentRunId?: AgentRunId\n readonly ref: string\n readonly summary: string\n readonly mediaType?: string\n readonly sizeBytes: number\n readonly sha256: string\n readonly createdInStageId: StageId\n readonly sourcePtapMessageId: string\n readonly createdAt: string\n}\n\n/** Protocol-facing draft. Small content may be inline; large content uses `ref`. */\nexport interface EvidenceSubmission {\n readonly kind: EvidenceKind\n readonly summary: string\n readonly content?: string\n readonly ref?: string\n readonly mediaType?: string\n}\n// ── from src/domain/finding.ts ────────────────────────────────────────\nexport const FINDING_STATUSES = [\n 'candidate',\n 'validating',\n 'confirmed',\n 'unconfirmed',\n 'false_positive',\n] as const\n\nexport type FindingStatus = (typeof FINDING_STATUSES)[number]\n\nexport const FINDING_SEVERITIES = ['info', 'low', 'medium', 'high', 'critical'] as const\n\nexport type FindingSeverity = (typeof FINDING_SEVERITIES)[number]\n\nexport interface Finding {\n readonly id: FindingId\n readonly engagementId: EngagementId\n readonly title: string\n readonly severity: FindingSeverity\n readonly confidence: number\n readonly status: FindingStatus\n readonly occurrenceIds: readonly FindingOccurrenceId[]\n readonly category?: string\n readonly weakness?: string\n readonly cwe?: string\n readonly identityKey?: string\n readonly createdInStageId?: StageId\n readonly producedByTaskId?: TaskId\n readonly producedByAgentRunId?: AgentRunId\n}\n\nexport interface FindingOccurrence {\n readonly id: FindingOccurrenceId\n readonly findingId: FindingId\n readonly engagementId: EngagementId\n readonly assetId: AssetId\n readonly endpoint?: string\n readonly serviceId?: string\n readonly evidenceIds: readonly EvidenceId[]\n readonly reproductionContext?: string\n readonly status: FindingStatus\n readonly identityKey?: string\n}\n\nexport interface FindingOccurrenceSubmission {\n readonly assetId: string\n readonly endpoint?: string\n readonly serviceId?: string\n readonly evidenceRefs?: readonly string[]\n readonly reproductionContext?: string\n}\n\n/** Protocol-facing draft. PTES Core assigns `FindingId` on persist. */\nexport interface FindingSubmission {\n readonly title: string\n readonly severity: FindingSeverity\n readonly confidence: number\n readonly status: FindingStatus\n readonly summary?: string\n readonly category?: string\n readonly weakness?: string\n readonly cwe?: string\n readonly occurrence?: FindingOccurrenceSubmission\n}\n// ── from src/domain/ptes-core.ts ────────────────────────────────────────\nexport const PTES_CORE_INDEX_SCHEMA_VERSION = 1 as const\n\nexport type ArtifactRecord = Artifact\nexport type FindingRecord = Finding\nexport type FindingOccurrenceRecord = FindingOccurrence\n\nexport interface EvidenceRecord extends Evidence {\n readonly resourceRef: ContextResourceRef\n}\n\nexport type ArtifactUpsertStatus = 'created' | 'merged'\nexport type FindingUpsertStatus = 'created' | 'merged'\nexport type OccurrenceUpsertStatus = 'created' | 'merged'\n\nexport interface ArtifactUpsertResult {\n readonly status: ArtifactUpsertStatus\n readonly artifact: ArtifactRecord\n}\n\nexport interface FindingUpsertResult {\n readonly status: FindingUpsertStatus\n readonly finding: FindingRecord\n}\n\nexport interface FindingOccurrenceUpsertResult {\n readonly status: OccurrenceUpsertStatus\n readonly occurrence: FindingOccurrenceRecord\n readonly finding: FindingRecord\n}\n\nexport type IngestionResult =\n | {\n readonly type: 'artifact'\n readonly artifactId: ArtifactId\n readonly status: ArtifactUpsertStatus\n }\n | {\n readonly type: 'evidence'\n readonly evidenceId: EvidenceId\n }\n | {\n readonly type: 'finding'\n readonly findingId: FindingId\n readonly occurrenceId?: FindingOccurrenceId\n readonly findingStatus: FindingUpsertStatus\n readonly occurrenceStatus?: OccurrenceUpsertStatus\n }\n\nexport interface ArtifactQuery {\n readonly kind?: Artifact['kind']\n readonly identityKey?: string\n}\n\nexport interface EvidenceQuery {\n readonly kind?: Evidence['kind']\n}\n\nexport interface FindingQuery {\n readonly status?: FindingStatus\n readonly identityKey?: string\n}\n\nexport interface EvidenceStorageLimits {\n readonly maxEvidenceBytes: number\n}\n\nexport const DEFAULT_EVIDENCE_STORAGE_LIMITS: EvidenceStorageLimits = {\n maxEvidenceBytes: 8 * 1024 * 1024,\n}\n\nexport interface PtesCoreIndexMeta {\n readonly schemaVersion: typeof PTES_CORE_INDEX_SCHEMA_VERSION\n readonly lastEventSequence: number\n}\n\nexport interface ArtifactIndexSnapshot extends PtesCoreIndexMeta {\n readonly artifacts: Readonly<Record<string, ArtifactRecord>>\n readonly artifactIdsByIdentityKey: Readonly<Record<string, ArtifactId>>\n}\n\nexport interface EvidenceIndexSnapshot extends PtesCoreIndexMeta {\n readonly evidence: Readonly<Record<string, EvidenceRecord>>\n}\n\nexport interface FindingIndexSnapshot extends PtesCoreIndexMeta {\n readonly findings: Readonly<Record<string, FindingRecord>>\n readonly occurrences: Readonly<Record<string, FindingOccurrenceRecord>>\n readonly findingIdsByIdentityKey: Readonly<Record<string, FindingId>>\n readonly occurrenceIdsByIdentityKey: Readonly<Record<string, FindingOccurrenceId>>\n}\n\nexport interface IngestionIndexSnapshot extends PtesCoreIndexMeta {\n readonly results: Readonly<Record<string, IngestionResult>>\n}\n\nexport interface PtesCoreState {\n readonly schemaVersion: typeof PTES_CORE_INDEX_SCHEMA_VERSION\n readonly lastEventSequence: number\n readonly engagementId: EngagementId\n readonly artifacts: Readonly<Record<string, ArtifactRecord>>\n readonly artifactIdsByIdentityKey: Readonly<Record<string, ArtifactId>>\n readonly evidence: Readonly<Record<string, EvidenceRecord>>\n readonly findings: Readonly<Record<string, FindingRecord>>\n readonly occurrences: Readonly<Record<string, FindingOccurrenceRecord>>\n readonly findingIdsByIdentityKey: Readonly<Record<string, FindingId>>\n readonly occurrenceIdsByIdentityKey: Readonly<Record<string, FindingOccurrenceId>>\n readonly ingestion: Readonly<Record<string, IngestionResult>>\n}\n// ── from src/domain/tools.ts ────────────────────────────────────────\nexport const TOOL_CALL_STATUSES = [\n 'requested',\n 'pending_approval',\n 'queued',\n 'running',\n 'succeeded',\n 'failed',\n 'timed_out',\n 'cancelled',\n 'interrupted',\n 'denied',\n 'capability_required',\n] as const\n\nexport type ToolCallStatus = (typeof TOOL_CALL_STATUSES)[number]\n\nexport const TOOL_RISK_DECISIONS = ['AUTO', 'APPROVAL', 'DENY'] as const\nexport type ToolRiskDecision = (typeof TOOL_RISK_DECISIONS)[number]\n\nexport const TOOL_OPERATION_CLASSES = [\n 'sandbox_setup',\n 'recon',\n 'read_only_validation',\n 'target_state_change',\n 'high_risk',\n 'escape',\n] as const\nexport type ToolOperationClass = (typeof TOOL_OPERATION_CLASSES)[number]\n\nexport const TOOL_FAILURE_KINDS = [\n 'timeout',\n 'transport',\n 'execution',\n 'backend_unavailable',\n 'toolbox_image_unavailable',\n 'cancelled',\n 'invalid_result',\n 'unknown',\n] as const\nexport type ToolFailureKind = (typeof TOOL_FAILURE_KINDS)[number]\n\nexport const TOOLBOX_LIFECYCLES = ['agent_run', 'engagement'] as const\nexport type ToolboxLifecycle = (typeof TOOLBOX_LIFECYCLES)[number]\n\nexport const MCP_LIFECYCLES = ['agent_run', 'engagement'] as const\nexport type McpLifecycle = (typeof MCP_LIFECYCLES)[number]\n\nexport const DOCKER_RUNTIME_STATUSES = ['running', 'stopped', 'missing', 'unhealthy', 'unknown'] as const\nexport type DockerRuntimeStatus = (typeof DOCKER_RUNTIME_STATUSES)[number]\n\nexport const MCP_RUNTIME_STATUSES = ['connected', 'reconnectable', 'stopped', 'unavailable', 'unknown'] as const\nexport type McpRuntimeStatus = (typeof MCP_RUNTIME_STATUSES)[number]\n\nexport const IMAGE_RESOLVE_SOURCES = ['existing', 'built', 'pulled'] as const\nexport type ImageResolveSource = (typeof IMAGE_RESOLVE_SOURCES)[number]\n\nexport const TOOL_RETRY_HINTS = ['transient', 'permanent', 'unknown'] as const\nexport type ToolRetryHint = (typeof TOOL_RETRY_HINTS)[number]\n\nexport const TOOL_TERMINATIONS = ['confirmed', 'requested', 'unknown'] as const\nexport type ToolTermination = (typeof TOOL_TERMINATIONS)[number]\n\nexport type ToolBackendBinding =\n | { readonly kind: 'docker'; readonly executor: string }\n | { readonly kind: 'mcp'; readonly serverId: McpServerId; readonly remoteToolName: string }\n\nexport interface ToolTimeoutSpec {\n readonly defaultMs: number\n readonly maxMs: number\n}\n\nexport interface ToolScopeTarget {\n readonly value: string\n}\n\nexport interface ToolCallRequest {\n readonly engagementId: EngagementId\n readonly taskId: TaskId\n readonly agentRunId: AgentRunId\n readonly toolId: ToolId\n readonly arguments: unknown\n readonly timeoutMs?: number\n readonly retryOf?: ToolCallId\n}\n\nexport interface ToolDefinition {\n readonly id: ToolId\n readonly name: string\n readonly description: string\n readonly toolboxId: ToolboxId\n readonly backend: ToolBackendBinding\n readonly risk: ToolRiskDecision\n readonly timeout: ToolTimeoutSpec\n readonly requiredArgumentKeys?: readonly string[]\n readonly scopeTargets?: (args: Record<string, unknown>) => readonly ToolScopeTarget[]\n}\n\nexport interface ToolboxProvisioning {\n readonly dockerfile?: {\n readonly context: string\n readonly dockerfile: string\n }\n readonly pull?: {\n readonly image: string\n }\n}\n\nexport interface ToolboxDefinition {\n readonly id: ToolboxId\n readonly name: string\n readonly description: string\n readonly toolIds: readonly ToolId[]\n readonly image: string\n readonly lifecycle: ToolboxLifecycle\n readonly provisioning?: ToolboxProvisioning\n readonly env?: Readonly<Record<string, string>>\n readonly secrets?: Readonly<Record<string, string>>\n}\n\nexport type ContainerExecSpec =\n | {\n readonly mode: 'argv'\n readonly toolboxId: ToolboxId\n readonly executable: string\n readonly args?: readonly string[]\n readonly cwd?: string\n readonly env?: Readonly<Record<string, string>>\n readonly timeoutMs?: number\n readonly operationClass?: ToolOperationClass\n readonly declaredTargets?: readonly ToolScopeTarget[]\n }\n | {\n readonly mode: 'shell'\n readonly toolboxId: ToolboxId\n readonly command: string\n readonly cwd?: string\n readonly env?: Readonly<Record<string, string>>\n readonly timeoutMs?: number\n readonly operationClass?: ToolOperationClass\n readonly declaredTargets?: readonly ToolScopeTarget[]\n }\n\n/** @deprecated Prefer ContainerExecSpec; kept as the parsed argv-shaped view. */\nexport interface ContainerExecArguments {\n readonly toolboxId: ToolboxId\n readonly mode: 'argv' | 'shell'\n readonly command: string\n readonly executable?: string\n readonly args?: readonly string[]\n readonly cwd?: string\n readonly env?: Readonly<Record<string, string>>\n readonly timeoutMs?: number\n readonly operationClass?: ToolOperationClass\n readonly declaredTargets?: readonly ToolScopeTarget[]\n}\n\nexport interface ToolOutputLimits {\n readonly maxInlineOutputBytes: number\n readonly maxTotalCapturedBytes: number\n}\n\nexport const DEFAULT_TOOL_OUTPUT_LIMITS: ToolOutputLimits = {\n maxInlineOutputBytes: 8_192,\n maxTotalCapturedBytes: 1_048_576,\n}\n\nexport interface DockerToolboxBinding {\n readonly engagementId: EngagementId\n readonly agentRunId?: AgentRunId\n readonly toolboxId: ToolboxId\n readonly lifecycle: ToolboxLifecycle\n readonly containerId: string\n readonly image: string\n readonly imageId?: string\n readonly imageSource?: ImageResolveSource\n}\n\nexport interface McpTransportDefinition {\n readonly kind: 'fixture' | 'stdio' | 'http'\n readonly command?: string\n readonly args?: readonly string[]\n readonly url?: string\n}\n\nexport interface McpServerConfig {\n readonly env?: Readonly<Record<string, string>>\n readonly secrets?: Readonly<Record<string, string>>\n}\n\nexport interface McpServerDefinition {\n readonly id: McpServerId\n readonly name: string\n readonly lifecycle: McpLifecycle\n readonly transport: McpTransportDefinition\n readonly config: McpServerConfig\n}\n\nexport interface McpRuntimeBinding {\n readonly engagementId: EngagementId\n readonly agentRunId?: AgentRunId\n readonly serverId: McpServerId\n readonly lifecycle: McpLifecycle\n readonly runtimeId?: string\n}\n\nexport interface ToolOutputResourceRef extends ContextResourceRef {}\n\nexport interface ToolCallRecord {\n readonly toolCallId: ToolCallId\n readonly request: ToolCallRequest\n readonly status: ToolCallStatus\n readonly createdAt: string\n readonly updatedAt: string\n readonly retryOf?: ToolCallId\n readonly reason?: string\n readonly outputRefs?: readonly ToolOutputResourceRef[]\n readonly retryHint?: ToolRetryHint\n readonly failureKind?: ToolFailureKind\n readonly termination?: ToolTermination\n readonly policySnapshot?: {\n readonly risk?: ToolRiskDecision\n readonly scope?: 'allowed' | 'denied'\n }\n}\n\nexport interface PendingToolCall {\n readonly toolCallId: ToolCallId\n readonly request: ToolCallRequest\n readonly status: 'pending_approval'\n readonly requestedAt: string\n readonly policySnapshot: {\n readonly risk: 'APPROVAL'\n readonly scope: 'allowed'\n readonly toolboxId: ToolboxId\n }\n}\n\nexport interface ToolBrokerConcurrencyLimits {\n readonly maxPerEngagement: number\n readonly maxPerAgentRun: number\n}\n\nexport const DEFAULT_TOOL_BROKER_LIMITS: ToolBrokerConcurrencyLimits = {\n maxPerEngagement: 4,\n maxPerAgentRun: 2,\n}\n// ── from src/domain/context.ts ────────────────────────────────────────\nexport const CONTEXT_TRUST_LEVELS = [\n 'system',\n 'user',\n 'trusted_internal',\n 'untrusted_external',\n] as const\nexport type ContextTrustLevel = (typeof CONTEXT_TRUST_LEVELS)[number]\n\nexport const CONTEXT_SOURCE_TYPES = [\n 'engagement',\n 'task',\n 'agent_run',\n 'asset',\n 'artifact',\n 'evidence',\n 'finding',\n 'user',\n] as const\nexport type ContextSourceType = (typeof CONTEXT_SOURCE_TYPES)[number]\n\nexport const CONTEXT_ITEM_KINDS = [\n 'asset',\n 'artifact',\n 'finding',\n 'evidence',\n 'related_task',\n 'guidance',\n] as const\nexport type ContextItemKind = (typeof CONTEXT_ITEM_KINDS)[number]\n\nexport type ContextPriority = 1 | 2 | 3 | 4 | 5 | 6\n\nexport interface ContextSource {\n readonly type: ContextSourceType\n readonly sourceId?: string\n readonly producedByTaskId?: TaskId\n readonly producedByAgentRunId?: AgentRunId\n readonly createdInStageId?: StageId\n readonly contentKind?: string\n}\n\nexport interface ContextResourceRef {\n readonly resourceId: string\n readonly kind: string\n readonly mediaType?: string\n readonly sizeBytes?: number\n}\n\nexport interface InlineContextContent {\n readonly text: string\n readonly mediaType?: string\n}\n\nexport interface ContextItemBase {\n readonly id: string\n readonly kind: ContextItemKind\n readonly trust: ContextTrustLevel\n readonly source: ContextSource\n readonly summary?: string\n readonly content?: InlineContextContent\n readonly ref?: ContextResourceRef\n readonly priority: ContextPriority\n}\n\nexport type AssetContextItem = ContextItemBase & { readonly kind: 'asset' }\nexport type ArtifactContextItem = ContextItemBase & { readonly kind: 'artifact' }\nexport type FindingContextItem = ContextItemBase & { readonly kind: 'finding' }\nexport type EvidenceContextItem = ContextItemBase & { readonly kind: 'evidence' }\nexport type RelatedTaskContextItem = ContextItemBase & { readonly kind: 'related_task' }\nexport type UserGuidanceContextItem = ContextItemBase & { readonly kind: 'guidance' }\n\nexport type ContextItem =\n | AssetContextItem\n | ArtifactContextItem\n | FindingContextItem\n | EvidenceContextItem\n | RelatedTaskContextItem\n | UserGuidanceContextItem\n\nexport interface ContextConstraint {\n readonly id: string\n readonly text: string\n}\n\nexport interface EngagementContext {\n readonly id: EngagementId\n readonly objectives: string\n}\n\nexport interface ScopeContext {\n readonly id: string\n readonly summary: string\n}\n\nexport interface RoeContext {\n readonly summary: string\n}\n\nexport interface StageContext {\n readonly id: StageId\n readonly kind: PtesStageKind\n readonly status: string\n}\n\nexport interface TaskContext {\n readonly id: TaskId\n readonly goal: string\n readonly status: string\n readonly stageId: StageId\n readonly parentTaskId?: TaskId\n}\n\nexport interface AgentTemplateContext {\n readonly id: AgentTemplateId\n readonly name: string\n readonly role: string\n /**\n * POLICY METADATA ONLY — never rendered as \"available tools\". The actual\n * model-facing tools come from the Worker Tool Manifest (resolveWorkerTools).\n */\n readonly capabilities: readonly string[]\n}\n\nexport interface TaskLineageContext {\n readonly parentTaskId?: TaskId\n readonly parentSummary?: string\n}\n\nexport interface ContextBundleMetadata {\n readonly builtAt: string\n readonly itemCount: number\n}\n\nexport interface ContextDeltaMetadata {\n readonly builtAt: string\n readonly addedCount: number\n}\n\nexport interface TaskContextBundle {\n readonly engagement: EngagementContext\n readonly scope: ScopeContext\n readonly roe: RoeContext\n readonly stage: StageContext\n readonly task: TaskContext\n readonly agentTemplate: AgentTemplateContext\n readonly lineage: TaskLineageContext\n readonly assets: readonly AssetContextItem[]\n readonly artifacts: readonly ArtifactContextItem[]\n readonly findings: readonly FindingContextItem[]\n readonly evidence: readonly EvidenceContextItem[]\n readonly relatedTasks: readonly RelatedTaskContextItem[]\n readonly userGuidance: readonly UserGuidanceContextItem[]\n readonly constraints: readonly ContextConstraint[]\n readonly metadata: ContextBundleMetadata\n}\n\nexport interface TaskContextDelta {\n readonly task: TaskContext\n readonly addedItems: readonly ContextItem[]\n readonly addedRefs: readonly ContextResourceRef[]\n readonly userGuidance: readonly UserGuidanceContextItem[]\n readonly changedConstraints: readonly ContextConstraint[]\n readonly metadata: ContextDeltaMetadata\n}\n\nexport interface ContextBudget {\n readonly maxAssets: number\n readonly maxArtifacts: number\n readonly maxFindings: number\n readonly maxEvidenceRefs: number\n readonly maxRelatedTasks: number\n readonly maxUserGuidance: number\n readonly maxContextItems: number\n readonly maxEstimatedChars: number\n readonly maxInlineChars: number\n readonly maxMandatoryChars: number\n}\n\nexport interface ExplicitContextRef {\n readonly id: string\n readonly required?: boolean\n}\n\nexport interface ContextDeliveryState {\n readonly agentRunId: AgentRunId\n readonly deliveredItemIds: readonly string[]\n readonly deliveredRefIds: readonly string[]\n readonly revision: number\n readonly constraintFingerprint?: string\n}\n\nexport const CONTEXT_BUILD_ERROR_CODES = [\n 'context_state_invalid',\n 'task_not_found',\n 'agent_run_not_found',\n 'template_not_found',\n 'scope_missing',\n 'unresolved_required_ref',\n 'mandatory_context_too_large',\n 'delivery_state_invalid',\n 'provider_failure',\n] as const\n\nexport type ContextBuildErrorCode = (typeof CONTEXT_BUILD_ERROR_CODES)[number]\n\n// ── PTES stage constants (Wave 5: moved from workflow to break the\n// engagement-store ↔ workflow import cycle) ──\nexport const PTES_STAGE_KINDS = [\n 'pre-engagement',\n 'intelligence-gathering',\n 'threat-modeling',\n 'vulnerability-analysis',\n 'exploitation',\n 'post-exploitation',\n 'reporting',\n] as const\n\nexport type PtesStageKind = (typeof PTES_STAGE_KINDS)[number]\n\n// ── from src/domain/workflow/stage-definition.ts ────────────────────────────────────────\nexport interface StageDefinition {\n readonly id: PtesStageKind\n readonly name: string\n readonly order: number\n readonly description: string\n}\n\nexport const PTES_STAGE_DEFINITIONS: readonly StageDefinition[] = [\n {\n id: 'pre-engagement',\n name: 'Pre-engagement',\n order: 1,\n description: 'Authorize the assessment, record objectives, and establish Scope and initial Assets.',\n },\n {\n id: 'intelligence-gathering',\n name: 'Intelligence Gathering',\n order: 2,\n description: 'Discover Assets, services, endpoints, technologies, and observations inside Scope.',\n },\n {\n id: 'threat-modeling',\n name: 'Threat Modeling',\n order: 3,\n description: 'Turn known Assets and observations into attack surface, paths, priorities, and hypotheses.',\n },\n {\n id: 'vulnerability-analysis',\n name: 'Vulnerability Analysis',\n order: 4,\n description: 'Produce candidate Findings, Evidence, and validation Tasks from attack paths.',\n },\n {\n id: 'exploitation',\n name: 'Exploitation',\n order: 5,\n description: 'Validate candidate Findings into confirmed, unconfirmed, or false positive outcomes.',\n },\n {\n id: 'post-exploitation',\n name: 'Post Exploitation',\n order: 6,\n description: 'Assess impact, privileges, reachability, and updated attack paths.',\n },\n {\n id: 'reporting',\n name: 'Reporting',\n order: 7,\n description: 'Consume Scope, Artifacts, Evidence, Findings, and timeline into a Report.',\n },\n]\n"],"mappings":";AAwBA,SAAgB,MAAwB,OAAkB;CACxD,OAAO;AACT;AAEA,MAAa,gBAAgB;CAAC;CAAkB;CAAc;AAAS;AAmBvE,MAAa,iBAAiB;CAAC;CAAW;CAAU;CAAa;AAAS;AAI1E,MAAa,2BAA2B;CAAC;CAAY;CAAmB;AAAM;AAe9E,MAAa,gBAAgB;CAC3B;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAgBA,MAAa,iBAAiB;CAC5B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAIA,MAAa,iCAAiC;CAAC;CAAS;CAAW;CAAY;AAAY;AA2D3F,MAAa,qBAAqB;CAChC;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAqCA,MAAa,iBAAiB;CAC5B;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AA6BA,MAAa,mBAAmB;CAC9B;CACA;CACA;CACA;CACA;AACF;AAIA,MAAa,qBAAqB;CAAC;CAAQ;CAAO;CAAU;CAAQ;AAAU;AAyH9E,MAAa,kCAAyD,EACpE,kBAAkB,QACpB;AA0MA,MAAa,6BAA+C;CAC1D,sBAAsB;CACtB,uBAAuB;AACzB;AA8EA,MAAa,6BAA0D;CACrE,kBAAkB;CAClB,gBAAgB;AAClB;AAiNA,MAAa,mBAAmB;CAC9B;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAYA,MAAa,yBAAqD;CAChE;EACE,IAAI;EACJ,MAAM;EACN,OAAO;EACP,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,OAAO;EACP,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,OAAO;EACP,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,OAAO;EACP,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,OAAO;EACP,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,OAAO;EACP,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,OAAO;EACP,aAAa;CACf;AACF"}