@hunsu/protocol 0.1.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 (47) hide show
  1. package/LICENSE +157 -0
  2. package/dist/command-decoder.d.ts +5 -0
  3. package/dist/command-decoder.js +329 -0
  4. package/dist/constants.d.ts +15 -0
  5. package/dist/constants.js +15 -0
  6. package/dist/decoder-helpers.d.ts +58 -0
  7. package/dist/decoder-helpers.js +1757 -0
  8. package/dist/errors.d.ts +14 -0
  9. package/dist/errors.js +28 -0
  10. package/dist/event-decoder.d.ts +5 -0
  11. package/dist/event-decoder.js +232 -0
  12. package/dist/index.d.ts +10 -0
  13. package/dist/index.js +10 -0
  14. package/dist/lifecycle.d.ts +67 -0
  15. package/dist/lifecycle.js +271 -0
  16. package/dist/model.d.ts +1058 -0
  17. package/dist/model.js +1 -0
  18. package/dist/primitives.d.ts +59 -0
  19. package/dist/primitives.js +135 -0
  20. package/dist/projection.d.ts +8 -0
  21. package/dist/projection.js +875 -0
  22. package/dist/prompt-template.d.ts +12 -0
  23. package/dist/prompt-template.js +83 -0
  24. package/dist/protocol-validation.d.ts +36 -0
  25. package/dist/protocol-validation.js +1139 -0
  26. package/dist/result.d.ts +20 -0
  27. package/dist/result.js +21 -0
  28. package/dist/workflow-helpers.d.ts +31 -0
  29. package/dist/workflow-helpers.js +193 -0
  30. package/dist/workflow.d.ts +10 -0
  31. package/dist/workflow.js +594 -0
  32. package/package.json +30 -0
  33. package/src/command-decoder.ts +292 -0
  34. package/src/constants.ts +27 -0
  35. package/src/decoder-helpers.ts +1672 -0
  36. package/src/errors.ts +38 -0
  37. package/src/event-decoder.ts +225 -0
  38. package/src/index.ts +43 -0
  39. package/src/lifecycle.ts +403 -0
  40. package/src/model.ts +1233 -0
  41. package/src/primitives.ts +196 -0
  42. package/src/projection.ts +1081 -0
  43. package/src/prompt-template.ts +97 -0
  44. package/src/protocol-validation.ts +1252 -0
  45. package/src/result.ts +35 -0
  46. package/src/workflow-helpers.ts +239 -0
  47. package/src/workflow.ts +753 -0
@@ -0,0 +1,1058 @@
1
+ import type { Brand, DestinationAcceptanceCriterion, DestinationConstraint, DestinationNotes, DestinationTitle, TeamName, EvidenceText, FailureReason, MoveCommit, NonEmptyArray, NonEmptyText, NonNegativeInteger, PositiveInteger, RequestGoal, RequestTitle, RiskText, SingleItemArray, Summary } from "./primitives.ts";
2
+ import type { PromptTemplate } from "./prompt-template.ts";
3
+ export type { TeamName } from "./primitives.ts";
4
+ export type Raw<T> = T extends (string & {
5
+ readonly __brand: string;
6
+ }) ? string : T extends (number & {
7
+ readonly __brand: string;
8
+ }) ? number : T extends readonly [infer First, ...infer Rest] ? [Raw<First>, ...{
9
+ [K in keyof Rest]: Raw<Rest[K]>;
10
+ }] : T extends readonly (infer Item)[] ? Raw<Item>[] : T extends object ? {
11
+ [K in keyof T]: Raw<T[K]>;
12
+ } : T;
13
+ export type DomainRole = "TEAM" | "DIRECTOR" | "SYSTEM";
14
+ export type SerializedIsoTimestamp = string;
15
+ export type RequestId = Brand<string, "RequestId">;
16
+ export type DestinationId = Brand<string, "DestinationId">;
17
+ export type MoveId = Brand<string, "MoveId">;
18
+ export type HunsuId = Brand<string, "HunsuId">;
19
+ export type HunsuDraftId = Brand<string, "HunsuDraftId">;
20
+ export type LineId = Brand<string, "LineId">;
21
+ export type NodeId = Brand<string, "NodeId">;
22
+ export type ArtifactId = Brand<string, "ArtifactId">;
23
+ export type ArtifactActionId = Brand<string, "ArtifactActionId">;
24
+ export type TeamId = Brand<string, "TeamId">;
25
+ export type SkillDraftId = Brand<string, "SkillDraftId">;
26
+ export type AgentConversationHash = Brand<string, "AgentConversationHash">;
27
+ export type ExecuteId = Brand<string, "ExecuteId">;
28
+ export type RouteId = Brand<string, "RouteId">;
29
+ export type WorktreeHash = Brand<string, "WorktreeHash">;
30
+ export type AgentContextHash = NonEmptyText;
31
+ export type AgentThreadId = NonEmptyText;
32
+ export type ExecutorId = NonEmptyText;
33
+ export type ManagerId = NonEmptyText;
34
+ export type ResourceId = Brand<string, "ResourceId">;
35
+ export type PathId = NonEmptyText;
36
+ export type MemberModelName = NonEmptyText;
37
+ export type MemberSkillName = NonEmptyText;
38
+ export type FutureConstraintText = NonEmptyText;
39
+ export type DestinationStatus = "pending" | "claimed" | "in_progress" | "reached" | "blocked" | "superseded" | "canceled";
40
+ export type DestinationSeed = {
41
+ id: DestinationId;
42
+ title: DestinationTitle;
43
+ acceptanceCriteria?: DestinationAcceptanceCriterion[];
44
+ constraints?: DestinationConstraint[];
45
+ priority?: number;
46
+ notes?: DestinationNotes;
47
+ };
48
+ export type DestinationSeedInput = Raw<DestinationSeed>;
49
+ export type DestinationSource = "initial-execute-team" | "initial-request" | "hunsu";
50
+ export type DestinationBase = DestinationSeed & {
51
+ requestId: RequestId;
52
+ source: DestinationSource;
53
+ createdBy: DomainRole;
54
+ updatedBy: DomainRole;
55
+ createdAt?: SerializedIsoTimestamp;
56
+ updatedAt?: SerializedIsoTimestamp;
57
+ };
58
+ export type PendingDestination = DestinationBase & {
59
+ status: "pending";
60
+ claimedBy?: never;
61
+ reachedByMoveId?: never;
62
+ blockedReason?: never;
63
+ canceledReason?: never;
64
+ supersededByDestinationId?: never;
65
+ };
66
+ export type ClaimedDestination = DestinationBase & {
67
+ status: "claimed";
68
+ claimedBy: string;
69
+ reachedByMoveId?: never;
70
+ blockedReason?: never;
71
+ canceledReason?: never;
72
+ supersededByDestinationId?: never;
73
+ };
74
+ export type InProgressDestination = DestinationBase & {
75
+ status: "in_progress";
76
+ claimedBy: string;
77
+ reachedByMoveId?: never;
78
+ blockedReason?: never;
79
+ canceledReason?: never;
80
+ supersededByDestinationId?: never;
81
+ };
82
+ export type ReachedDestination = DestinationBase & {
83
+ status: "reached";
84
+ reachedByMoveId: MoveId;
85
+ claimedBy?: string;
86
+ blockedReason?: never;
87
+ canceledReason?: never;
88
+ supersededByDestinationId?: never;
89
+ };
90
+ export type BlockedDestination = DestinationBase & {
91
+ status: "blocked";
92
+ blockedReason: string;
93
+ claimedBy?: string;
94
+ reachedByMoveId?: never;
95
+ canceledReason?: never;
96
+ supersededByDestinationId?: never;
97
+ };
98
+ export type SupersededDestination = DestinationBase & {
99
+ status: "superseded";
100
+ supersededByDestinationId: DestinationId;
101
+ claimedBy?: string;
102
+ reachedByMoveId?: never;
103
+ blockedReason?: never;
104
+ canceledReason?: never;
105
+ };
106
+ export type CanceledDestination = DestinationBase & {
107
+ status: "canceled";
108
+ canceledReason: string;
109
+ claimedBy?: string;
110
+ reachedByMoveId?: never;
111
+ blockedReason?: never;
112
+ supersededByDestinationId?: never;
113
+ };
114
+ export type Destination = PendingDestination | ClaimedDestination | InProgressDestination | ReachedDestination | BlockedDestination | SupersededDestination | CanceledDestination;
115
+ export type RequestRecord = {
116
+ id: RequestId;
117
+ title: RequestTitle;
118
+ goal: RequestGoal;
119
+ createdBy: DomainRole;
120
+ createdAt?: SerializedIsoTimestamp;
121
+ };
122
+ export type SkillSnapshotFile = {
123
+ path: NonEmptyText;
124
+ text: string;
125
+ };
126
+ export type LocalSnapshotSkillMetadata = {
127
+ kind: "local-snapshot";
128
+ name: NonEmptyText;
129
+ sourcePath: NonEmptyText;
130
+ contentHash: NonEmptyText;
131
+ snapshotRef: NonEmptyText;
132
+ snapshotFiles?: SkillSnapshotFile[];
133
+ };
134
+ export type LocalRootInstalledSkillMetadata = {
135
+ kind: "local-root-installed";
136
+ name: NonEmptyText;
137
+ sourcePath?: NonEmptyText;
138
+ };
139
+ export type RegistryPackageSkillMetadata = {
140
+ kind: "registry-package";
141
+ registryKind: "apm";
142
+ name: NonEmptyText;
143
+ registry: NonEmptyText;
144
+ package: NonEmptyText;
145
+ version: NonEmptyText;
146
+ integrity: NonEmptyText;
147
+ contentHash: NonEmptyText;
148
+ };
149
+ export type SkillMetaSkillMetadata = {
150
+ kind: "skillMeta";
151
+ name: NonEmptyText;
152
+ source: NonEmptyText;
153
+ agent: "codex";
154
+ };
155
+ export type MemberSkillMetadata = LocalSnapshotSkillMetadata | LocalRootInstalledSkillMetadata | RegistryPackageSkillMetadata | SkillMetaSkillMetadata;
156
+ export type SkillBinding = MemberSkillMetadata;
157
+ export type LocalRootInstalledPluginBinding = {
158
+ kind: "local-root-installed";
159
+ id: string;
160
+ };
161
+ export type MemberPluginBinding = LocalRootInstalledPluginBinding;
162
+ export type HubPackageKind = "team" | "member" | "manager" | "skill";
163
+ export type HubPackageLock = {
164
+ origin: NonEmptyText;
165
+ kind: HubPackageKind;
166
+ key: NonEmptyText;
167
+ version: NonEmptyText;
168
+ integrity: NonEmptyText;
169
+ };
170
+ export type ExecutorPackageBinding = {
171
+ executorId: ExecutorId;
172
+ lock: HubPackageLock;
173
+ };
174
+ export type ResourcePackageBinding = {
175
+ name: MemberSkillName;
176
+ lock: HubPackageLock;
177
+ };
178
+ export type HunsuOriginTransport = "http" | "ssh";
179
+ export type HunsuOrigin = {
180
+ name: NonEmptyText;
181
+ url: NonEmptyText;
182
+ transport: HunsuOriginTransport;
183
+ identity?: NonEmptyText;
184
+ };
185
+ export type ReasoningEffort = "default" | "minimal" | "low" | "medium" | "high" | "xhigh";
186
+ export type ServiceTier = "default" | "fast";
187
+ export type MemberExecutionNetwork = "disabled" | "enabled";
188
+ export type MemberExecutionConstraint = {
189
+ kind: "read_only";
190
+ network: MemberExecutionNetwork;
191
+ } | {
192
+ kind: "worktree_write";
193
+ network: MemberExecutionNetwork;
194
+ } | {
195
+ kind: "unrestricted";
196
+ network: MemberExecutionNetwork;
197
+ };
198
+ export type MemberApprovalsReviewer = "user" | "auto_review";
199
+ export type MemberApprovalConstraint = {
200
+ policy: "never";
201
+ } | {
202
+ policy: "on_request";
203
+ reviewer: MemberApprovalsReviewer;
204
+ };
205
+ export type GuardrailScope = "input" | "output" | "context" | "artifact" | "final_evidence";
206
+ export type GuardrailSeverity = "warn" | "block";
207
+ export type GuardrailConfig = {
208
+ name: NonEmptyText;
209
+ scope: GuardrailScope;
210
+ rule: NonEmptyText;
211
+ severity: GuardrailSeverity;
212
+ };
213
+ export type ResourceBinding = {
214
+ kind: "skill";
215
+ skill: SkillBinding;
216
+ } | {
217
+ kind: "plugin";
218
+ plugin: MemberPluginBinding;
219
+ } | {
220
+ kind: "package";
221
+ lock: HubPackageLock;
222
+ };
223
+ export type RuntimePolicy = {
224
+ model: MemberModelName;
225
+ reasoningEffort: ReasoningEffort;
226
+ serviceTier?: ServiceTier;
227
+ execution: MemberExecutionConstraint;
228
+ approval: MemberApprovalConstraint;
229
+ };
230
+ export type TeamPlanner = {
231
+ promptTemplate: PromptTemplate;
232
+ maxAttemptCount?: PositiveInteger;
233
+ guardrails?: GuardrailConfig[];
234
+ };
235
+ export type ExecutorVisibleProfile = {
236
+ kind: "team" | "member";
237
+ label?: NonEmptyText;
238
+ summary?: NonEmptyText;
239
+ capabilities?: NonEmptyText[];
240
+ };
241
+ export type Membership = {
242
+ executorId: ExecutorId;
243
+ visibleProfile: ExecutorVisibleProfile;
244
+ };
245
+ export type Team = {
246
+ kind: "team";
247
+ id: ExecutorId;
248
+ planner: TeamPlanner;
249
+ members: Membership[];
250
+ };
251
+ export type Member = {
252
+ kind: "member";
253
+ id: ExecutorId;
254
+ promptTemplate: PromptTemplate;
255
+ resources: ResourceBinding[];
256
+ runtimePolicy: RuntimePolicy;
257
+ };
258
+ export type Executor = Team | Member;
259
+ export type ExecutorEntity = Executor & {
260
+ packageLock?: HubPackageLock;
261
+ };
262
+ export type ResourceEntity = {
263
+ id: ResourceId;
264
+ binding: ResourceBinding;
265
+ packageLock?: HubPackageLock;
266
+ };
267
+ export type Harness = {
268
+ rootTeamId: ExecutorId;
269
+ executors: ExecutorEntity[];
270
+ resources: ResourceEntity[];
271
+ guardrails: GuardrailConfig[];
272
+ artifactActions: ArtifactActionDefinition[];
273
+ };
274
+ export type MemberConfig = {
275
+ id: ExecutorId;
276
+ promptTemplate: PromptTemplate;
277
+ skills: MemberSkillMetadata[];
278
+ plugins: MemberPluginBinding[];
279
+ model: MemberModelName;
280
+ reasoningEffort: ReasoningEffort;
281
+ serviceTier?: ServiceTier;
282
+ execution: MemberExecutionConstraint;
283
+ approval: MemberApprovalConstraint;
284
+ };
285
+ export type ManagerConfig = {
286
+ id: ManagerId;
287
+ promptTemplate: PromptTemplate;
288
+ skills: SkillBinding[];
289
+ plugins: MemberPluginBinding[];
290
+ };
291
+ export type MemberPath = {
292
+ id: PathId;
293
+ executorId: ExecutorId;
294
+ goal: string;
295
+ requires: PathId[] | "PrevMove";
296
+ };
297
+ export type QueueExecutionPlan = {
298
+ kind: "queue";
299
+ id: PathId;
300
+ items: ExecutionPlan[];
301
+ };
302
+ export type ExecutionContinuation = {
303
+ kind: "continuation";
304
+ id: PathId;
305
+ teamScopeId: ExecutorId;
306
+ execution: ExecutionPlan;
307
+ continuation?: GoalExecutionPlan;
308
+ };
309
+ export type GoalPathEvaluationStage = {
310
+ kind: "goal";
311
+ stage: "needs_evaluation";
312
+ id: PathId;
313
+ assignee: {
314
+ executorId: ExecutorId;
315
+ goal: string;
316
+ };
317
+ evaluator?: {
318
+ executorId: ExecutorId;
319
+ prompt: string;
320
+ };
321
+ remainingAttempts: NonNegativeInteger;
322
+ requires: MemberPath["requires"];
323
+ };
324
+ export type GoalExecutionPlanStage = {
325
+ kind: "goal";
326
+ stage: "needs_execution";
327
+ id: PathId;
328
+ assignee: {
329
+ executorId: ExecutorId;
330
+ goal: string;
331
+ };
332
+ evaluator?: {
333
+ executorId: ExecutorId;
334
+ prompt: string;
335
+ };
336
+ remainingAttempts: NonNegativeInteger;
337
+ evaluationPathId: PathId;
338
+ evaluation: Extract<GoalEvaluation, {
339
+ type: "fail";
340
+ }>;
341
+ requires: PathId[];
342
+ };
343
+ export type GoalExecutionPlan = GoalPathEvaluationStage | GoalExecutionPlanStage;
344
+ export type ExecutionPlan = QueueExecutionPlan | GoalExecutionPlan | ExecutionContinuation;
345
+ export type GoalEvaluation = {
346
+ type: "pass";
347
+ summary: string;
348
+ evidence?: string[];
349
+ } | {
350
+ type: "fail";
351
+ reason: string;
352
+ feedback: string;
353
+ nextGoal?: string;
354
+ evidence?: string[];
355
+ };
356
+ export type TeamExecutionPlanHarnessSnapshot = {
357
+ kind: "team_execution_plan";
358
+ maxAttemptCount: PositiveInteger;
359
+ guardrails?: GuardrailConfig[];
360
+ team: {
361
+ promptTemplate: PromptTemplate;
362
+ };
363
+ members: MemberConfig[];
364
+ };
365
+ export type TeamExecutionPlanHarnessPlannerSnapshot = Omit<TeamExecutionPlanHarnessSnapshot, "members"> & {
366
+ members?: never;
367
+ };
368
+ export type RoleSquadHarnessSnapshot = {
369
+ kind: "role_squad";
370
+ maxRoundCount: PositiveInteger;
371
+ guardrails?: GuardrailConfig[];
372
+ team: {
373
+ promptTemplate: PromptTemplate;
374
+ };
375
+ members: MemberConfig[];
376
+ };
377
+ export type RoleSquadHarnessPlannerSnapshot = Omit<RoleSquadHarnessSnapshot, "members"> & {
378
+ members?: never;
379
+ };
380
+ export type CouncilVoteHarnessSnapshot = {
381
+ kind: "council_vote";
382
+ maxRoundCount: PositiveInteger;
383
+ voteRule: "majority" | "unanimous" | "weighted" | "coordinator_decides";
384
+ guardrails?: GuardrailConfig[];
385
+ team: {
386
+ promptTemplate: PromptTemplate;
387
+ };
388
+ members: MemberConfig[];
389
+ };
390
+ export type CouncilVoteHarnessPlannerSnapshot = Omit<CouncilVoteHarnessSnapshot, "members"> & {
391
+ members?: never;
392
+ };
393
+ export type CourtDebateHarnessSnapshot = {
394
+ kind: "court_debate";
395
+ preset?: "security_review";
396
+ maxRoundCount: PositiveInteger;
397
+ guardrails?: GuardrailConfig[];
398
+ team: {
399
+ promptTemplate: PromptTemplate;
400
+ };
401
+ members: MemberConfig[];
402
+ };
403
+ export type CourtDebateHarnessPlannerSnapshot = Omit<CourtDebateHarnessSnapshot, "members"> & {
404
+ members?: never;
405
+ };
406
+ export type HarnessSnapshot = TeamExecutionPlanHarnessSnapshot | RoleSquadHarnessSnapshot | CouncilVoteHarnessSnapshot | CourtDebateHarnessSnapshot;
407
+ export type HarnessPlannerSnapshot = TeamExecutionPlanHarnessPlannerSnapshot | RoleSquadHarnessPlannerSnapshot | CouncilVoteHarnessPlannerSnapshot | CourtDebateHarnessPlannerSnapshot;
408
+ export type HarnessSnapshotInput = Raw<HarnessSnapshot>;
409
+ export type SkillDraftBase = {
410
+ id: SkillDraftId;
411
+ name: NonEmptyText;
412
+ sourcePath?: NonEmptyText;
413
+ draftPath: NonEmptyText;
414
+ createdFromNodeId?: NodeId;
415
+ createdAt?: SerializedIsoTimestamp;
416
+ };
417
+ export type DraftSkillDraft = SkillDraftBase & {
418
+ status: "draft";
419
+ acceptedSnapshot?: never;
420
+ };
421
+ export type AcceptedSkillDraft = SkillDraftBase & {
422
+ status: "accepted";
423
+ acceptedSnapshot: SkillBinding;
424
+ };
425
+ export type DiscardedSkillDraft = SkillDraftBase & {
426
+ status: "discarded";
427
+ acceptedSnapshot?: never;
428
+ };
429
+ export type SkillDraftRecord = DraftSkillDraft | AcceptedSkillDraft | DiscardedSkillDraft;
430
+ export type AgentConversationRefBase = {
431
+ conversationHash: AgentConversationHash;
432
+ contextHash: AgentContextHash;
433
+ worktreeHash?: WorktreeHash;
434
+ startedAt: SerializedIsoTimestamp;
435
+ };
436
+ export type ActiveCodexAgentConversationRef = AgentConversationRefBase & {
437
+ provider: "codex";
438
+ threadId?: AgentThreadId;
439
+ endedAt?: never;
440
+ };
441
+ export type EndedCodexAgentConversationRef = AgentConversationRefBase & {
442
+ provider: "codex";
443
+ threadId?: AgentThreadId;
444
+ endedAt: SerializedIsoTimestamp;
445
+ };
446
+ export type ActiveLocalAgentConversationRef = AgentConversationRefBase & {
447
+ provider: "local";
448
+ threadId?: never;
449
+ endedAt?: never;
450
+ };
451
+ export type EndedLocalAgentConversationRef = AgentConversationRefBase & {
452
+ provider: "local";
453
+ threadId?: never;
454
+ endedAt: SerializedIsoTimestamp;
455
+ };
456
+ export type AgentConversationRef = ActiveCodexAgentConversationRef | EndedCodexAgentConversationRef | ActiveLocalAgentConversationRef | EndedLocalAgentConversationRef;
457
+ export type AgentConversationRefInput = Raw<AgentConversationRef>;
458
+ export type AgentConversationAccessMode = "READ" | "CONVERSE" | "TRANSACT";
459
+ export type WorktreeRefBase = {
460
+ worktreeHash: WorktreeHash;
461
+ path: NonEmptyText;
462
+ branch: NonEmptyText;
463
+ baseRef: NonEmptyText;
464
+ createdAt: SerializedIsoTimestamp;
465
+ };
466
+ export type ActiveWorktreeRef = WorktreeRefBase & {
467
+ removedAt?: never;
468
+ };
469
+ export type RemovedWorktreeRef = WorktreeRefBase & {
470
+ removedAt: SerializedIsoTimestamp;
471
+ };
472
+ export type WorktreeRef = ActiveWorktreeRef | RemovedWorktreeRef;
473
+ export type RouteRecordBase = {
474
+ routeId: RouteId;
475
+ sourceLineId: LineId;
476
+ sourceNodeId: NodeId;
477
+ targetNodeId?: NodeId;
478
+ worktree: WorktreeRef;
479
+ agentSessionId?: string;
480
+ };
481
+ export type PlanRoute = RouteRecordBase & {
482
+ kind: "Plan";
483
+ access: "READ";
484
+ currentExecutionPath: ".hunsu/current-execution.hunsu";
485
+ chat?: never;
486
+ readyDraft?: never;
487
+ };
488
+ export type PathRoute = RouteRecordBase & {
489
+ kind: "Path";
490
+ access: "READ";
491
+ pathId: PathId;
492
+ executorId: ExecutorId;
493
+ chat?: never;
494
+ readyDraft?: never;
495
+ };
496
+ export type DraftHunsuDraftRoute = RouteRecordBase & {
497
+ kind: "HunsuDraft";
498
+ access: "CONVERSE";
499
+ status: "draft";
500
+ readyDraft?: never;
501
+ confirmedHunsuId?: never;
502
+ confirmedNodeId?: never;
503
+ };
504
+ export type ReadyHunsuDraftRoute = RouteRecordBase & {
505
+ kind: "HunsuDraft";
506
+ access: "CONVERSE";
507
+ status: "ready";
508
+ readyDraft: ReadyHunsuDraft;
509
+ confirmedHunsuId?: never;
510
+ confirmedNodeId?: never;
511
+ };
512
+ export type ConfirmedHunsuDraftRoute = RouteRecordBase & {
513
+ kind: "HunsuDraft";
514
+ access: "CONVERSE";
515
+ status: "confirmed";
516
+ readyDraft: ReadyHunsuDraft;
517
+ confirmedHunsuId: HunsuId;
518
+ confirmedNodeId: NodeId;
519
+ };
520
+ export type DiscardedHunsuDraftRoute = RouteRecordBase & {
521
+ kind: "HunsuDraft";
522
+ access: "CONVERSE";
523
+ status: "discarded";
524
+ readyDraft?: never;
525
+ confirmedHunsuId?: never;
526
+ confirmedNodeId?: never;
527
+ };
528
+ export type FailedHunsuDraftRoute = RouteRecordBase & {
529
+ kind: "HunsuDraft";
530
+ access: "CONVERSE";
531
+ status: "failed";
532
+ error: FailureReason;
533
+ readyDraft?: never;
534
+ confirmedHunsuId?: never;
535
+ confirmedNodeId?: never;
536
+ };
537
+ export type HunsuDraftRoute = DraftHunsuDraftRoute | ReadyHunsuDraftRoute | ConfirmedHunsuDraftRoute | DiscardedHunsuDraftRoute | FailedHunsuDraftRoute;
538
+ export type RouteRecord = PlanRoute | PathRoute | HunsuDraftRoute;
539
+ export type WorktreeRefInput = Raw<WorktreeRef>;
540
+ export type ArtifactActionKind = "host" | "check";
541
+ export type ArtifactActionSourceScope = "move" | "commit" | "move-or-commit";
542
+ export type ArtifactActionScalar = string | number | boolean;
543
+ export type ArtifactActionEnvValue = {
544
+ default: ArtifactActionScalar;
545
+ } | {
546
+ value: ArtifactActionScalar;
547
+ } | {
548
+ required: true;
549
+ secret?: boolean;
550
+ } | {
551
+ alias: NonEmptyText;
552
+ } | {
553
+ fromAliasUrl: NonEmptyText;
554
+ };
555
+ export type ArtifactActionServiceAlias = {
556
+ service: NonEmptyText;
557
+ containerPort: PositiveInteger;
558
+ healthPath?: NonEmptyText;
559
+ target?: never;
560
+ };
561
+ export type ArtifactActionTargetAlias = {
562
+ target: NonEmptyText;
563
+ service?: never;
564
+ containerPort?: never;
565
+ healthPath?: never;
566
+ };
567
+ export type ArtifactActionAlias = ArtifactActionServiceAlias | ArtifactActionTargetAlias;
568
+ export type ArtifactActionEvidenceSettings = {
569
+ attach?: boolean;
570
+ paths?: NonEmptyText[];
571
+ };
572
+ export type ArtifactActionDockerComposeRunner = {
573
+ type: "docker_compose";
574
+ file: NonEmptyText;
575
+ projectName?: NonEmptyText;
576
+ };
577
+ export type ArtifactActionCommandRunner = {
578
+ type: "command";
579
+ command: NonEmptyText;
580
+ stopCommand?: NonEmptyText;
581
+ };
582
+ export type ArtifactActionRunner = ArtifactActionDockerComposeRunner | ArtifactActionCommandRunner;
583
+ export type ArtifactActionDefinition = {
584
+ id: ArtifactActionId;
585
+ title: NonEmptyText;
586
+ kind: ArtifactActionKind;
587
+ sourceScope: ArtifactActionSourceScope;
588
+ env?: Record<string, ArtifactActionEnvValue>;
589
+ runner: ArtifactActionRunner;
590
+ aliases?: Record<string, ArtifactActionAlias>;
591
+ evidence?: ArtifactActionEvidenceSettings;
592
+ displayOrder: number;
593
+ };
594
+ export type ArtifactActionDefinitionInput = Raw<ArtifactActionDefinition>;
595
+ export type ArtifactActionPatch = Partial<Omit<ArtifactActionDefinition, "id">>;
596
+ export type TeamSnapshot = {
597
+ teamName: TeamName;
598
+ moveOrdinal: number;
599
+ destinations: Destination[];
600
+ harness: HarnessSnapshot;
601
+ harnessGraph: Harness;
602
+ harnessLock?: HubPackageLock;
603
+ executorPackageBindings?: ExecutorPackageBinding[];
604
+ resourcePackageBindings?: ResourcePackageBinding[];
605
+ artifactActions: ArtifactActionDefinition[];
606
+ };
607
+ export type MoveOutcome = "arrived" | "accident";
608
+ export type MoveRecordBase = {
609
+ id: MoveId;
610
+ lineId: LineId;
611
+ fromNodeId: NodeId;
612
+ toNodeId: NodeId;
613
+ teamName?: TeamName;
614
+ ordinal?: number;
615
+ snapshot?: TeamSnapshot;
616
+ sourceHunsuId?: HunsuId;
617
+ executeId?: ExecuteId;
618
+ conversationRef?: AgentConversationRef;
619
+ worktree?: WorktreeRef;
620
+ summary: Summary;
621
+ commit: MoveCommit;
622
+ evidence: EvidenceText[];
623
+ risks?: RiskText[];
624
+ recordedBy: "SYSTEM";
625
+ recordedAt?: SerializedIsoTimestamp;
626
+ };
627
+ export type ArrivedMoveRecord = MoveRecordBase & {
628
+ outcome: "arrived";
629
+ reachedDestinationIds: SingleItemArray<DestinationId>;
630
+ failureReason?: never;
631
+ };
632
+ export type AccidentMoveRecord = MoveRecordBase & {
633
+ outcome: "accident";
634
+ reachedDestinationIds: [];
635
+ failureReason: FailureReason;
636
+ };
637
+ export type MoveRecord = ArrivedMoveRecord | AccidentMoveRecord;
638
+ export type HunsuChangedFileKind = "added" | "updated" | "removed";
639
+ export type HunsuChangedFile = {
640
+ path: NonEmptyText;
641
+ kind: HunsuChangedFileKind;
642
+ summary: Summary;
643
+ };
644
+ export type HunsuChangedFileInput = Raw<HunsuChangedFile>;
645
+ export type HunsuDraftStatus = "draft" | "ready" | "confirmed" | "discarded";
646
+ export type HunsuDraftBase = {
647
+ id: HunsuDraftId;
648
+ sourceLineId: LineId;
649
+ sourceNodeId: NodeId;
650
+ sourceMoveId?: MoveId;
651
+ target: HunsuTarget;
652
+ newTeamName: TeamName;
653
+ summary: Summary;
654
+ teamSnapshot: TeamSnapshot;
655
+ changedFiles: HunsuChangedFile[];
656
+ createdAt?: SerializedIsoTimestamp;
657
+ updatedAt?: SerializedIsoTimestamp;
658
+ };
659
+ export type DraftHunsuDraft = HunsuDraftBase & {
660
+ status: "draft";
661
+ hunsuId?: never;
662
+ newLineId?: never;
663
+ conversationRef?: never;
664
+ };
665
+ export type ReadyHunsuDraft = HunsuDraftBase & {
666
+ status: "ready";
667
+ hunsuId: HunsuId;
668
+ newLineId: LineId;
669
+ conversationRef: AgentConversationRef;
670
+ };
671
+ export type ConfirmedHunsuDraft = HunsuDraftBase & {
672
+ status: "confirmed";
673
+ hunsuId: HunsuId;
674
+ newLineId: LineId;
675
+ conversationRef: AgentConversationRef;
676
+ };
677
+ export type DiscardedHunsuDraft = HunsuDraftBase & {
678
+ status: "discarded";
679
+ hunsuId?: never;
680
+ newLineId?: never;
681
+ conversationRef?: AgentConversationRef;
682
+ };
683
+ export type HunsuDraftRecord = DraftHunsuDraft | ReadyHunsuDraft | ConfirmedHunsuDraft | DiscardedHunsuDraft;
684
+ export type DestinationPatch = {
685
+ title?: DestinationTitle;
686
+ acceptanceCriteria?: DestinationAcceptanceCriterion[];
687
+ constraints?: DestinationConstraint[];
688
+ priority?: number;
689
+ notes?: DestinationNotes;
690
+ };
691
+ export type DestinationPatchInput = Raw<DestinationPatch>;
692
+ export type HunsuTarget = {
693
+ type: "destination";
694
+ id: DestinationId;
695
+ } | {
696
+ type: "move";
697
+ id: MoveId;
698
+ } | {
699
+ type: "line";
700
+ id: LineId;
701
+ } | {
702
+ type: "node";
703
+ id: NodeId;
704
+ };
705
+ export type HunsuTargetInput = Raw<HunsuTarget>;
706
+ export type HunsuRecord = {
707
+ id: HunsuId;
708
+ hunsuDraftId?: HunsuDraftId;
709
+ conversationRef?: AgentConversationRef;
710
+ lineId: LineId;
711
+ fromNodeId: NodeId;
712
+ toNodeId: NodeId;
713
+ target: HunsuTarget;
714
+ summary: Summary;
715
+ newLineId?: LineId;
716
+ sourceMoveId?: MoveId;
717
+ newTeamName?: TeamName;
718
+ teamSnapshot: TeamSnapshot;
719
+ changedFiles: HunsuChangedFile[];
720
+ recordedBy: "DIRECTOR";
721
+ recordedAt?: SerializedIsoTimestamp;
722
+ };
723
+ export type LineStatus = "active" | "paused" | "complete" | "failed" | "abandoned";
724
+ export type LineRoute = {
725
+ moveIds: MoveId[];
726
+ rootNodeId: NodeId;
727
+ currentNodeId: NodeId;
728
+ nodeIds: NonEmptyArray<NodeId>;
729
+ };
730
+ export type RootLineRecordBase = LineRoute & {
731
+ id: LineId;
732
+ requestId: RequestId;
733
+ teamName?: TeamName;
734
+ parentLineId?: never;
735
+ forkedFromMoveId?: never;
736
+ };
737
+ export type ForkedLineRecordBase = LineRoute & {
738
+ id: LineId;
739
+ requestId: RequestId;
740
+ teamName?: TeamName;
741
+ parentLineId: LineId;
742
+ forkedFromMoveId?: MoveId;
743
+ };
744
+ export type LineRecordBase = RootLineRecordBase | ForkedLineRecordBase;
745
+ export type ActiveLine = LineRecordBase & {
746
+ status: "active";
747
+ };
748
+ export type PausedLine = LineRecordBase & {
749
+ status: "paused";
750
+ };
751
+ export type CompleteLine = LineRecordBase & {
752
+ status: "complete";
753
+ };
754
+ export type FailedLine = LineRecordBase & {
755
+ status: "failed";
756
+ };
757
+ export type AbandonedLine = LineRecordBase & {
758
+ status: "abandoned";
759
+ };
760
+ export type LineRecord = ActiveLine | PausedLine | CompleteLine | FailedLine | AbandonedLine;
761
+ export type PlayableLine = ActiveLine;
762
+ export type NodeRecord = {
763
+ id: NodeId;
764
+ requestId: RequestId;
765
+ lineId?: LineId;
766
+ teamName?: TeamName;
767
+ ordinal: number;
768
+ destinations: Destination[];
769
+ harness: HarnessSnapshot;
770
+ harnessGraph: Harness;
771
+ harnessLock?: HubPackageLock;
772
+ executorPackageBindings?: ExecutorPackageBinding[];
773
+ resourcePackageBindings?: ResourcePackageBinding[];
774
+ artifactActions: ArtifactActionDefinition[];
775
+ source: {
776
+ type: "initial-execute-team";
777
+ requestId: RequestId;
778
+ } | {
779
+ type: "request";
780
+ requestId: RequestId;
781
+ } | {
782
+ type: "move";
783
+ moveId: MoveId;
784
+ fromNodeId: NodeId;
785
+ } | {
786
+ type: "hunsu";
787
+ hunsuId: HunsuId;
788
+ fromNodeId: NodeId;
789
+ };
790
+ createdAt?: SerializedIsoTimestamp;
791
+ };
792
+ export type BoardEdge = {
793
+ id: MoveId;
794
+ type: "move";
795
+ lineId: LineId;
796
+ fromNodeId: NodeId;
797
+ toNodeId: NodeId;
798
+ moveId: MoveId;
799
+ } | {
800
+ id: HunsuId;
801
+ type: "hunsu";
802
+ lineId: LineId;
803
+ fromNodeId: NodeId;
804
+ toNodeId: NodeId;
805
+ hunsuId: HunsuId;
806
+ };
807
+ export type ArtifactOwner = {
808
+ type: "move";
809
+ id: MoveId;
810
+ } | {
811
+ type: "hunsu";
812
+ id: HunsuId;
813
+ } | {
814
+ type: "line";
815
+ id: LineId;
816
+ };
817
+ export type ArtifactKind = "transcript" | "command-output" | "test-log" | "screenshot" | "diff-summary" | "note";
818
+ export type ArtifactRecordBase = {
819
+ id: ArtifactId;
820
+ owner: ArtifactOwner;
821
+ kind: ArtifactKind;
822
+ };
823
+ export type PathArtifact = ArtifactRecordBase & {
824
+ path: string;
825
+ text?: never;
826
+ };
827
+ export type TextArtifact = ArtifactRecordBase & {
828
+ path?: never;
829
+ text: string;
830
+ };
831
+ export type PathAndTextArtifact = ArtifactRecordBase & {
832
+ path: string;
833
+ text: string;
834
+ };
835
+ export type ArtifactRecord = PathArtifact | TextArtifact | PathAndTextArtifact;
836
+ export type ArtifactRecordInput = Raw<ArtifactRecord>;
837
+ export type ValidatedTeamCommand = {
838
+ type: "ClaimDestination";
839
+ destinationId: DestinationId;
840
+ actor: string;
841
+ at?: SerializedIsoTimestamp;
842
+ } | {
843
+ type: "StartDestinationWork";
844
+ destinationId: DestinationId;
845
+ actor: string;
846
+ at?: SerializedIsoTimestamp;
847
+ } | {
848
+ type: "ReportDestinationBlocked";
849
+ destinationId: DestinationId;
850
+ reason: FailureReason;
851
+ actor: string;
852
+ at?: SerializedIsoTimestamp;
853
+ } | {
854
+ type: "RecordMove";
855
+ lineId: LineId;
856
+ moveId: MoveId;
857
+ summary: Summary;
858
+ commit: MoveCommit;
859
+ reachedDestinationIds: SingleItemArray<DestinationId>;
860
+ evidence: EvidenceText[];
861
+ risks?: RiskText[];
862
+ executeId?: ExecuteId;
863
+ conversationRef?: AgentConversationRef;
864
+ worktree?: WorktreeRef;
865
+ actor: string;
866
+ at?: SerializedIsoTimestamp;
867
+ } | {
868
+ type: "RecordAccident";
869
+ lineId: LineId;
870
+ moveId: MoveId;
871
+ summary: Summary;
872
+ commit: MoveCommit;
873
+ evidence: EvidenceText[];
874
+ failureReason: FailureReason;
875
+ risks?: RiskText[];
876
+ executeId?: ExecuteId;
877
+ conversationRef?: AgentConversationRef;
878
+ worktree?: WorktreeRef;
879
+ actor: string;
880
+ at?: SerializedIsoTimestamp;
881
+ } | {
882
+ type: "AttachMoveEvidence";
883
+ moveId: MoveId;
884
+ artifact: ArtifactRecord;
885
+ actor: string;
886
+ at?: SerializedIsoTimestamp;
887
+ };
888
+ export type ValidatedDirectorCommand = {
889
+ type: "ConfirmHunsuDraft";
890
+ draft: ReadyHunsuDraft;
891
+ actor: string;
892
+ at?: SerializedIsoTimestamp;
893
+ } | {
894
+ type: "CreateSkillDraft";
895
+ draftId: SkillDraftId;
896
+ lineId: LineId;
897
+ name: NonEmptyText;
898
+ draftPath: NonEmptyText;
899
+ sourcePath?: NonEmptyText;
900
+ actor: string;
901
+ at?: SerializedIsoTimestamp;
902
+ } | {
903
+ type: "DiscardSkillDraft";
904
+ draftId: SkillDraftId;
905
+ actor: string;
906
+ at?: SerializedIsoTimestamp;
907
+ };
908
+ export type ValidatedSystemCommand = {
909
+ type: "RegisterHunsuOrigin";
910
+ origin: HunsuOrigin;
911
+ actor?: string;
912
+ at?: SerializedIsoTimestamp;
913
+ } | {
914
+ type: "CreateInitialTeam";
915
+ requestId: RequestId;
916
+ lineId: LineId;
917
+ title: RequestTitle;
918
+ goal: RequestGoal;
919
+ destinations: DestinationSeed[];
920
+ harness?: HarnessSnapshot;
921
+ harnessLock?: HubPackageLock;
922
+ teamName?: TeamName;
923
+ actor?: string;
924
+ at?: SerializedIsoTimestamp;
925
+ } | {
926
+ type: "StartLine";
927
+ lineId: LineId;
928
+ requestId: RequestId;
929
+ teamName?: TeamName;
930
+ at?: SerializedIsoTimestamp;
931
+ } | {
932
+ type: "PauseLine" | "ResumeLine";
933
+ lineId: LineId;
934
+ at?: SerializedIsoTimestamp;
935
+ } | {
936
+ type: "AcceptLine" | "RejectLine";
937
+ lineId: LineId;
938
+ reason?: string;
939
+ at?: SerializedIsoTimestamp;
940
+ } | {
941
+ type: "RecordArtifact";
942
+ artifact: ArtifactRecord;
943
+ at?: SerializedIsoTimestamp;
944
+ };
945
+ export type ValidatedCommand = ValidatedTeamCommand | ValidatedDirectorCommand | ValidatedSystemCommand;
946
+ export type TeamCommand = Raw<ValidatedTeamCommand>;
947
+ export type DirectorCommand = Raw<ValidatedDirectorCommand>;
948
+ export type SystemCommand = Raw<ValidatedSystemCommand>;
949
+ export type Command = Raw<ValidatedCommand>;
950
+ export type DomainEvent = {
951
+ type: "HunsuOriginRegistered";
952
+ origin: HunsuOrigin;
953
+ at?: SerializedIsoTimestamp;
954
+ } | {
955
+ type: "InitialTeamCreated";
956
+ request: RequestRecord;
957
+ line: LineRecord;
958
+ destinations: DestinationSeed[];
959
+ harness?: HarnessSnapshot;
960
+ harnessLock?: HubPackageLock;
961
+ at?: SerializedIsoTimestamp;
962
+ } | {
963
+ type: "RequestCreated";
964
+ request: RequestRecord;
965
+ } | {
966
+ type: "DestinationDeclared";
967
+ requestId: RequestId;
968
+ destination: DestinationSeed;
969
+ at?: SerializedIsoTimestamp;
970
+ } | {
971
+ type: "HarnessSeeded";
972
+ requestId: RequestId;
973
+ harness: HarnessSnapshot;
974
+ at?: SerializedIsoTimestamp;
975
+ } | {
976
+ type: "LineStarted";
977
+ line: LineRecord;
978
+ } | {
979
+ type: "SkillDraftCreated";
980
+ draft: SkillDraftRecord;
981
+ } | {
982
+ type: "SkillDraftAccepted";
983
+ draftId: SkillDraftId;
984
+ skill: SkillBinding;
985
+ at?: SerializedIsoTimestamp;
986
+ } | {
987
+ type: "SkillDraftDiscarded";
988
+ draftId: SkillDraftId;
989
+ at?: SerializedIsoTimestamp;
990
+ } | {
991
+ type: "NodeCreated";
992
+ node: NodeRecord;
993
+ } | {
994
+ type: "LinePaused" | "LineResumed";
995
+ lineId: LineId;
996
+ at?: SerializedIsoTimestamp;
997
+ } | {
998
+ type: "LineAccepted" | "LineRejected";
999
+ lineId: LineId;
1000
+ reason?: string;
1001
+ at?: SerializedIsoTimestamp;
1002
+ } | {
1003
+ type: "DestinationClaimed" | "DestinationWorkStarted";
1004
+ destinationId: DestinationId;
1005
+ actor: string;
1006
+ at?: SerializedIsoTimestamp;
1007
+ } | {
1008
+ type: "DestinationBlocked";
1009
+ destinationId: DestinationId;
1010
+ reason: string;
1011
+ actor: string;
1012
+ at?: SerializedIsoTimestamp;
1013
+ } | {
1014
+ type: "MoveRecorded";
1015
+ move: MoveRecord;
1016
+ } | {
1017
+ type: "DestinationReached";
1018
+ destinationId: DestinationId;
1019
+ moveId: MoveId;
1020
+ at?: SerializedIsoTimestamp;
1021
+ } | {
1022
+ type: "HunsuRecorded";
1023
+ hunsu: HunsuRecord;
1024
+ } | {
1025
+ type: "LineForkedByHunsu";
1026
+ hunsuId: HunsuId;
1027
+ fromLineId: LineId;
1028
+ newLineId: LineId;
1029
+ newTeamName?: TeamName;
1030
+ fromMoveId?: MoveId;
1031
+ requestId: RequestId;
1032
+ at?: SerializedIsoTimestamp;
1033
+ } | {
1034
+ type: "ArtifactRecorded";
1035
+ artifact: ArtifactRecord;
1036
+ at?: SerializedIsoTimestamp;
1037
+ };
1038
+ export type DomainEventInput = Raw<DomainEvent>;
1039
+ export type FutureConstraint = {
1040
+ hunsuId: HunsuId;
1041
+ lineId: LineId;
1042
+ constraint: FutureConstraintText;
1043
+ at?: SerializedIsoTimestamp;
1044
+ };
1045
+ export type BoardProjection = {
1046
+ origins: HunsuOrigin[];
1047
+ requests: RequestRecord[];
1048
+ destinations: Destination[];
1049
+ nodes: NodeRecord[];
1050
+ edges: BoardEdge[];
1051
+ lines: LineRecord[];
1052
+ moves: MoveRecord[];
1053
+ hunsus: HunsuRecord[];
1054
+ skillDrafts: SkillDraftRecord[];
1055
+ artifacts: ArtifactRecord[];
1056
+ artifactActions: ArtifactActionDefinition[];
1057
+ futureConstraints: FutureConstraint[];
1058
+ };