@raindancers/raindancers-crew 0.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.
package/API.md ADDED
@@ -0,0 +1,1821 @@
1
+ # API Reference <a name="API Reference" id="api-reference"></a>
2
+
3
+ ## Constructs <a name="Constructs" id="Constructs"></a>
4
+
5
+ ### CrewBackupBucket <a name="CrewBackupBucket" id="@raindancers/raindancers-crew.CrewBackupBucket"></a>
6
+
7
+ - *Implements:* <a href="#@raindancers/raindancers-crew.ICrewBackupBucket">ICrewBackupBucket</a>
8
+
9
+ A hardened S3 bucket for KiroCrew snapshot backups.
10
+
11
+ The snapshot bundle produced by `kirocrew snapshot --purpose backup` is
12
+ already redaction-scrubbed (the signing key, `.env`, and execution logs
13
+ never ship), so this stores portable crew state, not raw secrets. The bucket
14
+ is nonetheless locked down as if it did: SSE-KMS at rest, all public access
15
+ blocked, TLS-only access, versioned so an overwrite cannot destroy history,
16
+ and a lifecycle rule that expires stale noncurrent versions.
17
+
18
+ Use {@link grantWrite} to let an instance/task role push snapshots, and
19
+ {@link grantRead} to let a replacement instance pull them for restore.
20
+
21
+ #### Initializers <a name="Initializers" id="@raindancers/raindancers-crew.CrewBackupBucket.Initializer"></a>
22
+
23
+ ```typescript
24
+ import { CrewBackupBucket } from '@raindancers/raindancers-crew'
25
+
26
+ new CrewBackupBucket(scope: Construct, id: string, props?: CrewBackupBucketProps)
27
+ ```
28
+
29
+ | **Name** | **Type** | **Description** |
30
+ | --- | --- | --- |
31
+ | <code><a href="#@raindancers/raindancers-crew.CrewBackupBucket.Initializer.parameter.scope">scope</a></code> | <code>constructs.Construct</code> | *No description.* |
32
+ | <code><a href="#@raindancers/raindancers-crew.CrewBackupBucket.Initializer.parameter.id">id</a></code> | <code>string</code> | *No description.* |
33
+ | <code><a href="#@raindancers/raindancers-crew.CrewBackupBucket.Initializer.parameter.props">props</a></code> | <code><a href="#@raindancers/raindancers-crew.CrewBackupBucketProps">CrewBackupBucketProps</a></code> | *No description.* |
34
+
35
+ ---
36
+
37
+ ##### `scope`<sup>Required</sup> <a name="scope" id="@raindancers/raindancers-crew.CrewBackupBucket.Initializer.parameter.scope"></a>
38
+
39
+ - *Type:* constructs.Construct
40
+
41
+ ---
42
+
43
+ ##### `id`<sup>Required</sup> <a name="id" id="@raindancers/raindancers-crew.CrewBackupBucket.Initializer.parameter.id"></a>
44
+
45
+ - *Type:* string
46
+
47
+ ---
48
+
49
+ ##### `props`<sup>Optional</sup> <a name="props" id="@raindancers/raindancers-crew.CrewBackupBucket.Initializer.parameter.props"></a>
50
+
51
+ - *Type:* <a href="#@raindancers/raindancers-crew.CrewBackupBucketProps">CrewBackupBucketProps</a>
52
+
53
+ ---
54
+
55
+ #### Methods <a name="Methods" id="Methods"></a>
56
+
57
+ | **Name** | **Description** |
58
+ | --- | --- |
59
+ | <code><a href="#@raindancers/raindancers-crew.CrewBackupBucket.toString">toString</a></code> | Returns a string representation of this construct. |
60
+ | <code><a href="#@raindancers/raindancers-crew.CrewBackupBucket.with">with</a></code> | Applies one or more mixins to this construct. |
61
+ | <code><a href="#@raindancers/raindancers-crew.CrewBackupBucket.grantRead">grantRead</a></code> | Grant a principal permission to READ snapshots (and the KMS decrypt it needs). |
62
+ | <code><a href="#@raindancers/raindancers-crew.CrewBackupBucket.grantWrite">grantWrite</a></code> | Grant a principal permission to WRITE snapshots (and the KMS encrypt it needs). |
63
+
64
+ ---
65
+
66
+ ##### `toString` <a name="toString" id="@raindancers/raindancers-crew.CrewBackupBucket.toString"></a>
67
+
68
+ ```typescript
69
+ public toString(): string
70
+ ```
71
+
72
+ Returns a string representation of this construct.
73
+
74
+ ##### `with` <a name="with" id="@raindancers/raindancers-crew.CrewBackupBucket.with"></a>
75
+
76
+ ```typescript
77
+ public with(mixins: ...IMixin[]): IConstruct
78
+ ```
79
+
80
+ Applies one or more mixins to this construct.
81
+
82
+ Mixins are applied in order. The list of constructs is captured at the
83
+ start of the call, so constructs added by a mixin will not be visited.
84
+ Use multiple `with()` calls if subsequent mixins should apply to added
85
+ constructs.
86
+
87
+ ###### `mixins`<sup>Required</sup> <a name="mixins" id="@raindancers/raindancers-crew.CrewBackupBucket.with.parameter.mixins"></a>
88
+
89
+ - *Type:* ...constructs.IMixin[]
90
+
91
+ The mixins to apply.
92
+
93
+ ---
94
+
95
+ ##### `grantRead` <a name="grantRead" id="@raindancers/raindancers-crew.CrewBackupBucket.grantRead"></a>
96
+
97
+ ```typescript
98
+ public grantRead(grantee: IGrantable): void
99
+ ```
100
+
101
+ Grant a principal permission to READ snapshots (and the KMS decrypt it needs).
102
+
103
+ Used by a replacement instance restoring from backup.
104
+
105
+ ###### `grantee`<sup>Required</sup> <a name="grantee" id="@raindancers/raindancers-crew.CrewBackupBucket.grantRead.parameter.grantee"></a>
106
+
107
+ - *Type:* aws-cdk-lib.aws_iam.IGrantable
108
+
109
+ ---
110
+
111
+ ##### `grantWrite` <a name="grantWrite" id="@raindancers/raindancers-crew.CrewBackupBucket.grantWrite"></a>
112
+
113
+ ```typescript
114
+ public grantWrite(grantee: IGrantable): void
115
+ ```
116
+
117
+ Grant a principal permission to WRITE snapshots (and the KMS encrypt it needs).
118
+
119
+ Used by the crew instance/task role that pushes backups.
120
+
121
+ ###### `grantee`<sup>Required</sup> <a name="grantee" id="@raindancers/raindancers-crew.CrewBackupBucket.grantWrite.parameter.grantee"></a>
122
+
123
+ - *Type:* aws-cdk-lib.aws_iam.IGrantable
124
+
125
+ ---
126
+
127
+ #### Static Functions <a name="Static Functions" id="Static Functions"></a>
128
+
129
+ | **Name** | **Description** |
130
+ | --- | --- |
131
+ | <code><a href="#@raindancers/raindancers-crew.CrewBackupBucket.isConstruct">isConstruct</a></code> | Checks if `x` is a construct. |
132
+
133
+ ---
134
+
135
+ ##### `isConstruct` <a name="isConstruct" id="@raindancers/raindancers-crew.CrewBackupBucket.isConstruct"></a>
136
+
137
+ ```typescript
138
+ import { CrewBackupBucket } from '@raindancers/raindancers-crew'
139
+
140
+ CrewBackupBucket.isConstruct(x: any)
141
+ ```
142
+
143
+ Checks if `x` is a construct.
144
+
145
+ Use this method instead of `instanceof` to properly detect `Construct`
146
+ instances, even when the construct library is symlinked.
147
+
148
+ Explanation: in JavaScript, multiple copies of the `constructs` library on
149
+ disk are seen as independent, completely different libraries. As a
150
+ consequence, the class `Construct` in each copy of the `constructs` library
151
+ is seen as a different class, and an instance of one class will not test as
152
+ `instanceof` the other class. `npm install` will not create installations
153
+ like this, but users may manually symlink construct libraries together or
154
+ use a monorepo tool: in those cases, multiple copies of the `constructs`
155
+ library can be accidentally installed, and `instanceof` will behave
156
+ unpredictably. It is safest to avoid using `instanceof`, and using
157
+ this type-testing method instead.
158
+
159
+ ###### `x`<sup>Required</sup> <a name="x" id="@raindancers/raindancers-crew.CrewBackupBucket.isConstruct.parameter.x"></a>
160
+
161
+ - *Type:* any
162
+
163
+ Any object.
164
+
165
+ ---
166
+
167
+ #### Properties <a name="Properties" id="Properties"></a>
168
+
169
+ | **Name** | **Type** | **Description** |
170
+ | --- | --- | --- |
171
+ | <code><a href="#@raindancers/raindancers-crew.CrewBackupBucket.property.node">node</a></code> | <code>constructs.Node</code> | The tree node. |
172
+ | <code><a href="#@raindancers/raindancers-crew.CrewBackupBucket.property.bucket">bucket</a></code> | <code>aws-cdk-lib.aws_s3.IBucket</code> | The backup bucket. |
173
+ | <code><a href="#@raindancers/raindancers-crew.CrewBackupBucket.property.key">key</a></code> | <code>aws-cdk-lib.aws_kms.Key</code> | The KMS key encrypting the bucket. |
174
+
175
+ ---
176
+
177
+ ##### `node`<sup>Required</sup> <a name="node" id="@raindancers/raindancers-crew.CrewBackupBucket.property.node"></a>
178
+
179
+ ```typescript
180
+ public readonly node: Node;
181
+ ```
182
+
183
+ - *Type:* constructs.Node
184
+
185
+ The tree node.
186
+
187
+ ---
188
+
189
+ ##### `bucket`<sup>Required</sup> <a name="bucket" id="@raindancers/raindancers-crew.CrewBackupBucket.property.bucket"></a>
190
+
191
+ ```typescript
192
+ public readonly bucket: IBucket;
193
+ ```
194
+
195
+ - *Type:* aws-cdk-lib.aws_s3.IBucket
196
+
197
+ The backup bucket.
198
+
199
+ ---
200
+
201
+ ##### `key`<sup>Required</sup> <a name="key" id="@raindancers/raindancers-crew.CrewBackupBucket.property.key"></a>
202
+
203
+ ```typescript
204
+ public readonly key: Key;
205
+ ```
206
+
207
+ - *Type:* aws-cdk-lib.aws_kms.Key
208
+
209
+ The KMS key encrypting the bucket.
210
+
211
+ ---
212
+
213
+
214
+ ### FargateCrew <a name="FargateCrew" id="@raindancers/raindancers-crew.FargateCrew"></a>
215
+
216
+ Per-crew Fargate scaffolding for ONE KiroCrew remote crew: the two roles a task carries and the log group it writes to.
217
+
218
+ One per crew, alongside the shared {@link FargateCrewBase }. Deleting this
219
+ removes exactly one crew's identity and logs and leaves the cluster and its
220
+ siblings untouched. Port of the upstream `kirocrew-fargate-crew` template.
221
+
222
+ Security invariants preserved from upstream:
223
+ - The **task role** (the running container's identity, and the blast radius
224
+ one agent turn reaches) is created with NO policies and MUST NEVER be
225
+ granted `secretsmanager:GetSecretValue` — the model credential is already
226
+ in the container env, so the grant buys nothing while letting one turn read
227
+ every crew's secret.
228
+ - The **execution role** reads secrets scoped to `kirocrew/crew/<crew>/*`
229
+ only, with individually-listed actions (no prefix wildcards).
230
+ - Both assume-role policies carry an `aws:SourceAccount` condition so the
231
+ roles are not assumable on behalf of an unrelated stack's task.
232
+
233
+ #### Initializers <a name="Initializers" id="@raindancers/raindancers-crew.FargateCrew.Initializer"></a>
234
+
235
+ ```typescript
236
+ import { FargateCrew } from '@raindancers/raindancers-crew'
237
+
238
+ new FargateCrew(scope: Construct, id: string, props: FargateCrewProps)
239
+ ```
240
+
241
+ | **Name** | **Type** | **Description** |
242
+ | --- | --- | --- |
243
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrew.Initializer.parameter.scope">scope</a></code> | <code>constructs.Construct</code> | *No description.* |
244
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrew.Initializer.parameter.id">id</a></code> | <code>string</code> | *No description.* |
245
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrew.Initializer.parameter.props">props</a></code> | <code><a href="#@raindancers/raindancers-crew.FargateCrewProps">FargateCrewProps</a></code> | *No description.* |
246
+
247
+ ---
248
+
249
+ ##### `scope`<sup>Required</sup> <a name="scope" id="@raindancers/raindancers-crew.FargateCrew.Initializer.parameter.scope"></a>
250
+
251
+ - *Type:* constructs.Construct
252
+
253
+ ---
254
+
255
+ ##### `id`<sup>Required</sup> <a name="id" id="@raindancers/raindancers-crew.FargateCrew.Initializer.parameter.id"></a>
256
+
257
+ - *Type:* string
258
+
259
+ ---
260
+
261
+ ##### `props`<sup>Required</sup> <a name="props" id="@raindancers/raindancers-crew.FargateCrew.Initializer.parameter.props"></a>
262
+
263
+ - *Type:* <a href="#@raindancers/raindancers-crew.FargateCrewProps">FargateCrewProps</a>
264
+
265
+ ---
266
+
267
+ #### Methods <a name="Methods" id="Methods"></a>
268
+
269
+ | **Name** | **Description** |
270
+ | --- | --- |
271
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrew.toString">toString</a></code> | Returns a string representation of this construct. |
272
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrew.with">with</a></code> | Applies one or more mixins to this construct. |
273
+
274
+ ---
275
+
276
+ ##### `toString` <a name="toString" id="@raindancers/raindancers-crew.FargateCrew.toString"></a>
277
+
278
+ ```typescript
279
+ public toString(): string
280
+ ```
281
+
282
+ Returns a string representation of this construct.
283
+
284
+ ##### `with` <a name="with" id="@raindancers/raindancers-crew.FargateCrew.with"></a>
285
+
286
+ ```typescript
287
+ public with(mixins: ...IMixin[]): IConstruct
288
+ ```
289
+
290
+ Applies one or more mixins to this construct.
291
+
292
+ Mixins are applied in order. The list of constructs is captured at the
293
+ start of the call, so constructs added by a mixin will not be visited.
294
+ Use multiple `with()` calls if subsequent mixins should apply to added
295
+ constructs.
296
+
297
+ ###### `mixins`<sup>Required</sup> <a name="mixins" id="@raindancers/raindancers-crew.FargateCrew.with.parameter.mixins"></a>
298
+
299
+ - *Type:* ...constructs.IMixin[]
300
+
301
+ The mixins to apply.
302
+
303
+ ---
304
+
305
+ #### Static Functions <a name="Static Functions" id="Static Functions"></a>
306
+
307
+ | **Name** | **Description** |
308
+ | --- | --- |
309
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrew.isConstruct">isConstruct</a></code> | Checks if `x` is a construct. |
310
+
311
+ ---
312
+
313
+ ##### `isConstruct` <a name="isConstruct" id="@raindancers/raindancers-crew.FargateCrew.isConstruct"></a>
314
+
315
+ ```typescript
316
+ import { FargateCrew } from '@raindancers/raindancers-crew'
317
+
318
+ FargateCrew.isConstruct(x: any)
319
+ ```
320
+
321
+ Checks if `x` is a construct.
322
+
323
+ Use this method instead of `instanceof` to properly detect `Construct`
324
+ instances, even when the construct library is symlinked.
325
+
326
+ Explanation: in JavaScript, multiple copies of the `constructs` library on
327
+ disk are seen as independent, completely different libraries. As a
328
+ consequence, the class `Construct` in each copy of the `constructs` library
329
+ is seen as a different class, and an instance of one class will not test as
330
+ `instanceof` the other class. `npm install` will not create installations
331
+ like this, but users may manually symlink construct libraries together or
332
+ use a monorepo tool: in those cases, multiple copies of the `constructs`
333
+ library can be accidentally installed, and `instanceof` will behave
334
+ unpredictably. It is safest to avoid using `instanceof`, and using
335
+ this type-testing method instead.
336
+
337
+ ###### `x`<sup>Required</sup> <a name="x" id="@raindancers/raindancers-crew.FargateCrew.isConstruct.parameter.x"></a>
338
+
339
+ - *Type:* any
340
+
341
+ Any object.
342
+
343
+ ---
344
+
345
+ #### Properties <a name="Properties" id="Properties"></a>
346
+
347
+ | **Name** | **Type** | **Description** |
348
+ | --- | --- | --- |
349
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrew.property.node">node</a></code> | <code>constructs.Node</code> | The tree node. |
350
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrew.property.crew">crew</a></code> | <code>string</code> | The crew this construct scaffolds. |
351
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrew.property.executionRole">executionRole</a></code> | <code>aws-cdk-lib.aws_iam.Role</code> | Role ECS assumes BEFORE the container starts (secret fetch + log stream). |
352
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrew.property.logGroup">logGroup</a></code> | <code>aws-cdk-lib.aws_logs.LogGroup</code> | The crew's log group (`/kirocrew/crew/<crew>`). |
353
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrew.property.secretArnPattern">secretArnPattern</a></code> | <code>string</code> | The one secret ARN pattern the execution role may read. |
354
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrew.property.secretNamePrefix">secretNamePrefix</a></code> | <code>string</code> | Namespace a crew secret must be created under for the exec role to read it. |
355
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrew.property.taskRole">taskRole</a></code> | <code>aws-cdk-lib.aws_iam.Role</code> | Identity the RUNNING container carries. |
356
+
357
+ ---
358
+
359
+ ##### `node`<sup>Required</sup> <a name="node" id="@raindancers/raindancers-crew.FargateCrew.property.node"></a>
360
+
361
+ ```typescript
362
+ public readonly node: Node;
363
+ ```
364
+
365
+ - *Type:* constructs.Node
366
+
367
+ The tree node.
368
+
369
+ ---
370
+
371
+ ##### `crew`<sup>Required</sup> <a name="crew" id="@raindancers/raindancers-crew.FargateCrew.property.crew"></a>
372
+
373
+ ```typescript
374
+ public readonly crew: string;
375
+ ```
376
+
377
+ - *Type:* string
378
+
379
+ The crew this construct scaffolds.
380
+
381
+ ---
382
+
383
+ ##### `executionRole`<sup>Required</sup> <a name="executionRole" id="@raindancers/raindancers-crew.FargateCrew.property.executionRole"></a>
384
+
385
+ ```typescript
386
+ public readonly executionRole: Role;
387
+ ```
388
+
389
+ - *Type:* aws-cdk-lib.aws_iam.Role
390
+
391
+ Role ECS assumes BEFORE the container starts (secret fetch + log stream).
392
+
393
+ ---
394
+
395
+ ##### `logGroup`<sup>Required</sup> <a name="logGroup" id="@raindancers/raindancers-crew.FargateCrew.property.logGroup"></a>
396
+
397
+ ```typescript
398
+ public readonly logGroup: LogGroup;
399
+ ```
400
+
401
+ - *Type:* aws-cdk-lib.aws_logs.LogGroup
402
+
403
+ The crew's log group (`/kirocrew/crew/<crew>`).
404
+
405
+ ---
406
+
407
+ ##### `secretArnPattern`<sup>Required</sup> <a name="secretArnPattern" id="@raindancers/raindancers-crew.FargateCrew.property.secretArnPattern"></a>
408
+
409
+ ```typescript
410
+ public readonly secretArnPattern: string;
411
+ ```
412
+
413
+ - *Type:* string
414
+
415
+ The one secret ARN pattern the execution role may read.
416
+
417
+ ---
418
+
419
+ ##### `secretNamePrefix`<sup>Required</sup> <a name="secretNamePrefix" id="@raindancers/raindancers-crew.FargateCrew.property.secretNamePrefix"></a>
420
+
421
+ ```typescript
422
+ public readonly secretNamePrefix: string;
423
+ ```
424
+
425
+ - *Type:* string
426
+
427
+ Namespace a crew secret must be created under for the exec role to read it.
428
+
429
+ ---
430
+
431
+ ##### `taskRole`<sup>Required</sup> <a name="taskRole" id="@raindancers/raindancers-crew.FargateCrew.property.taskRole"></a>
432
+
433
+ ```typescript
434
+ public readonly taskRole: Role;
435
+ ```
436
+
437
+ - *Type:* aws-cdk-lib.aws_iam.Role
438
+
439
+ Identity the RUNNING container carries.
440
+
441
+ Created with no policies.
442
+
443
+ ---
444
+
445
+
446
+ ### FargateCrewBase <a name="FargateCrewBase" id="@raindancers/raindancers-crew.FargateCrewBase"></a>
447
+
448
+ Shared Fargate scaffolding for KiroCrew remote crews: the ECS cluster every crew task runs on and the egress-only security group they are placed in.
449
+
450
+ ONE per account and region. The per-crew roles and log group live in
451
+ {@link FargateCrew } (one per crew), so deleting a crew cannot delete the
452
+ cluster its siblings run on.
453
+
454
+ Port of the upstream `kirocrew-fargate-base` CloudFormation template.
455
+
456
+ #### Initializers <a name="Initializers" id="@raindancers/raindancers-crew.FargateCrewBase.Initializer"></a>
457
+
458
+ ```typescript
459
+ import { FargateCrewBase } from '@raindancers/raindancers-crew'
460
+
461
+ new FargateCrewBase(scope: Construct, id: string, props: FargateCrewBaseProps)
462
+ ```
463
+
464
+ | **Name** | **Type** | **Description** |
465
+ | --- | --- | --- |
466
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrewBase.Initializer.parameter.scope">scope</a></code> | <code>constructs.Construct</code> | *No description.* |
467
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrewBase.Initializer.parameter.id">id</a></code> | <code>string</code> | *No description.* |
468
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrewBase.Initializer.parameter.props">props</a></code> | <code><a href="#@raindancers/raindancers-crew.FargateCrewBaseProps">FargateCrewBaseProps</a></code> | *No description.* |
469
+
470
+ ---
471
+
472
+ ##### `scope`<sup>Required</sup> <a name="scope" id="@raindancers/raindancers-crew.FargateCrewBase.Initializer.parameter.scope"></a>
473
+
474
+ - *Type:* constructs.Construct
475
+
476
+ ---
477
+
478
+ ##### `id`<sup>Required</sup> <a name="id" id="@raindancers/raindancers-crew.FargateCrewBase.Initializer.parameter.id"></a>
479
+
480
+ - *Type:* string
481
+
482
+ ---
483
+
484
+ ##### `props`<sup>Required</sup> <a name="props" id="@raindancers/raindancers-crew.FargateCrewBase.Initializer.parameter.props"></a>
485
+
486
+ - *Type:* <a href="#@raindancers/raindancers-crew.FargateCrewBaseProps">FargateCrewBaseProps</a>
487
+
488
+ ---
489
+
490
+ #### Methods <a name="Methods" id="Methods"></a>
491
+
492
+ | **Name** | **Description** |
493
+ | --- | --- |
494
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrewBase.toString">toString</a></code> | Returns a string representation of this construct. |
495
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrewBase.with">with</a></code> | Applies one or more mixins to this construct. |
496
+
497
+ ---
498
+
499
+ ##### `toString` <a name="toString" id="@raindancers/raindancers-crew.FargateCrewBase.toString"></a>
500
+
501
+ ```typescript
502
+ public toString(): string
503
+ ```
504
+
505
+ Returns a string representation of this construct.
506
+
507
+ ##### `with` <a name="with" id="@raindancers/raindancers-crew.FargateCrewBase.with"></a>
508
+
509
+ ```typescript
510
+ public with(mixins: ...IMixin[]): IConstruct
511
+ ```
512
+
513
+ Applies one or more mixins to this construct.
514
+
515
+ Mixins are applied in order. The list of constructs is captured at the
516
+ start of the call, so constructs added by a mixin will not be visited.
517
+ Use multiple `with()` calls if subsequent mixins should apply to added
518
+ constructs.
519
+
520
+ ###### `mixins`<sup>Required</sup> <a name="mixins" id="@raindancers/raindancers-crew.FargateCrewBase.with.parameter.mixins"></a>
521
+
522
+ - *Type:* ...constructs.IMixin[]
523
+
524
+ The mixins to apply.
525
+
526
+ ---
527
+
528
+ #### Static Functions <a name="Static Functions" id="Static Functions"></a>
529
+
530
+ | **Name** | **Description** |
531
+ | --- | --- |
532
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrewBase.isConstruct">isConstruct</a></code> | Checks if `x` is a construct. |
533
+
534
+ ---
535
+
536
+ ##### `isConstruct` <a name="isConstruct" id="@raindancers/raindancers-crew.FargateCrewBase.isConstruct"></a>
537
+
538
+ ```typescript
539
+ import { FargateCrewBase } from '@raindancers/raindancers-crew'
540
+
541
+ FargateCrewBase.isConstruct(x: any)
542
+ ```
543
+
544
+ Checks if `x` is a construct.
545
+
546
+ Use this method instead of `instanceof` to properly detect `Construct`
547
+ instances, even when the construct library is symlinked.
548
+
549
+ Explanation: in JavaScript, multiple copies of the `constructs` library on
550
+ disk are seen as independent, completely different libraries. As a
551
+ consequence, the class `Construct` in each copy of the `constructs` library
552
+ is seen as a different class, and an instance of one class will not test as
553
+ `instanceof` the other class. `npm install` will not create installations
554
+ like this, but users may manually symlink construct libraries together or
555
+ use a monorepo tool: in those cases, multiple copies of the `constructs`
556
+ library can be accidentally installed, and `instanceof` will behave
557
+ unpredictably. It is safest to avoid using `instanceof`, and using
558
+ this type-testing method instead.
559
+
560
+ ###### `x`<sup>Required</sup> <a name="x" id="@raindancers/raindancers-crew.FargateCrewBase.isConstruct.parameter.x"></a>
561
+
562
+ - *Type:* any
563
+
564
+ Any object.
565
+
566
+ ---
567
+
568
+ #### Properties <a name="Properties" id="Properties"></a>
569
+
570
+ | **Name** | **Type** | **Description** |
571
+ | --- | --- | --- |
572
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrewBase.property.node">node</a></code> | <code>constructs.Node</code> | The tree node. |
573
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrewBase.property.cluster">cluster</a></code> | <code>aws-cdk-lib.aws_ecs.Cluster</code> | The ECS cluster crew tasks run on. |
574
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrewBase.property.cpuArchitecture">cpuArchitecture</a></code> | <code><a href="#@raindancers/raindancers-crew.FargateCpuArchitecture">FargateCpuArchitecture</a></code> | The architecture crew images must be built for. |
575
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrewBase.property.securityGroup">securityGroup</a></code> | <code>aws-cdk-lib.aws_ec2.SecurityGroup</code> | The egress-only task security group (no inbound). |
576
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrewBase.property.stackTag">stackTag</a></code> | <code>string</code> | The `kirocrew:fargate` discovery tag value. |
577
+
578
+ ---
579
+
580
+ ##### `node`<sup>Required</sup> <a name="node" id="@raindancers/raindancers-crew.FargateCrewBase.property.node"></a>
581
+
582
+ ```typescript
583
+ public readonly node: Node;
584
+ ```
585
+
586
+ - *Type:* constructs.Node
587
+
588
+ The tree node.
589
+
590
+ ---
591
+
592
+ ##### `cluster`<sup>Required</sup> <a name="cluster" id="@raindancers/raindancers-crew.FargateCrewBase.property.cluster"></a>
593
+
594
+ ```typescript
595
+ public readonly cluster: Cluster;
596
+ ```
597
+
598
+ - *Type:* aws-cdk-lib.aws_ecs.Cluster
599
+
600
+ The ECS cluster crew tasks run on.
601
+
602
+ ---
603
+
604
+ ##### `cpuArchitecture`<sup>Required</sup> <a name="cpuArchitecture" id="@raindancers/raindancers-crew.FargateCrewBase.property.cpuArchitecture"></a>
605
+
606
+ ```typescript
607
+ public readonly cpuArchitecture: FargateCpuArchitecture;
608
+ ```
609
+
610
+ - *Type:* <a href="#@raindancers/raindancers-crew.FargateCpuArchitecture">FargateCpuArchitecture</a>
611
+
612
+ The architecture crew images must be built for.
613
+
614
+ ---
615
+
616
+ ##### `securityGroup`<sup>Required</sup> <a name="securityGroup" id="@raindancers/raindancers-crew.FargateCrewBase.property.securityGroup"></a>
617
+
618
+ ```typescript
619
+ public readonly securityGroup: SecurityGroup;
620
+ ```
621
+
622
+ - *Type:* aws-cdk-lib.aws_ec2.SecurityGroup
623
+
624
+ The egress-only task security group (no inbound).
625
+
626
+ ---
627
+
628
+ ##### `stackTag`<sup>Required</sup> <a name="stackTag" id="@raindancers/raindancers-crew.FargateCrewBase.property.stackTag"></a>
629
+
630
+ ```typescript
631
+ public readonly stackTag: string;
632
+ ```
633
+
634
+ - *Type:* string
635
+
636
+ The `kirocrew:fargate` discovery tag value.
637
+
638
+ ---
639
+
640
+
641
+ ### RemoteCrewInstance <a name="RemoteCrewInstance" id="@raindancers/raindancers-crew.RemoteCrewInstance"></a>
642
+
643
+ A self-hosted KiroCrew gateway on a single EC2 instance, reached over SSM Session Manager with no inbound ports.
644
+
645
+ This is a pipeline-native, version-controlled CDK port of the upstream
646
+ `kirocrew-ec2` CloudFormation template
647
+ (github.com/kirodotdev/KiroCrew). It provisions the same shape — an IAM
648
+ role (SSM core + optional scoped S3 read) under a required permissions
649
+ boundary, an SSM-only security group, an IMDSv2-enforced instance on an
650
+ encrypted gp3 volume, and a WaitCondition that blocks stack completion
651
+ until the gateway is serving — but under your naming, boundary, and
652
+ deploy pipeline instead of an imperative `kirocrew cloud launch`.
653
+
654
+ Access is via SSM port-forward only; the public DNS output is for
655
+ diagnostics.
656
+
657
+ #### Initializers <a name="Initializers" id="@raindancers/raindancers-crew.RemoteCrewInstance.Initializer"></a>
658
+
659
+ ```typescript
660
+ import { RemoteCrewInstance } from '@raindancers/raindancers-crew'
661
+
662
+ new RemoteCrewInstance(scope: Construct, id: string, props: RemoteCrewInstanceProps)
663
+ ```
664
+
665
+ | **Name** | **Type** | **Description** |
666
+ | --- | --- | --- |
667
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstance.Initializer.parameter.scope">scope</a></code> | <code>constructs.Construct</code> | *No description.* |
668
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstance.Initializer.parameter.id">id</a></code> | <code>string</code> | *No description.* |
669
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstance.Initializer.parameter.props">props</a></code> | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstanceProps">RemoteCrewInstanceProps</a></code> | *No description.* |
670
+
671
+ ---
672
+
673
+ ##### `scope`<sup>Required</sup> <a name="scope" id="@raindancers/raindancers-crew.RemoteCrewInstance.Initializer.parameter.scope"></a>
674
+
675
+ - *Type:* constructs.Construct
676
+
677
+ ---
678
+
679
+ ##### `id`<sup>Required</sup> <a name="id" id="@raindancers/raindancers-crew.RemoteCrewInstance.Initializer.parameter.id"></a>
680
+
681
+ - *Type:* string
682
+
683
+ ---
684
+
685
+ ##### `props`<sup>Required</sup> <a name="props" id="@raindancers/raindancers-crew.RemoteCrewInstance.Initializer.parameter.props"></a>
686
+
687
+ - *Type:* <a href="#@raindancers/raindancers-crew.RemoteCrewInstanceProps">RemoteCrewInstanceProps</a>
688
+
689
+ ---
690
+
691
+ #### Methods <a name="Methods" id="Methods"></a>
692
+
693
+ | **Name** | **Description** |
694
+ | --- | --- |
695
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstance.toString">toString</a></code> | Returns a string representation of this construct. |
696
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstance.with">with</a></code> | Applies one or more mixins to this construct. |
697
+
698
+ ---
699
+
700
+ ##### `toString` <a name="toString" id="@raindancers/raindancers-crew.RemoteCrewInstance.toString"></a>
701
+
702
+ ```typescript
703
+ public toString(): string
704
+ ```
705
+
706
+ Returns a string representation of this construct.
707
+
708
+ ##### `with` <a name="with" id="@raindancers/raindancers-crew.RemoteCrewInstance.with"></a>
709
+
710
+ ```typescript
711
+ public with(mixins: ...IMixin[]): IConstruct
712
+ ```
713
+
714
+ Applies one or more mixins to this construct.
715
+
716
+ Mixins are applied in order. The list of constructs is captured at the
717
+ start of the call, so constructs added by a mixin will not be visited.
718
+ Use multiple `with()` calls if subsequent mixins should apply to added
719
+ constructs.
720
+
721
+ ###### `mixins`<sup>Required</sup> <a name="mixins" id="@raindancers/raindancers-crew.RemoteCrewInstance.with.parameter.mixins"></a>
722
+
723
+ - *Type:* ...constructs.IMixin[]
724
+
725
+ The mixins to apply.
726
+
727
+ ---
728
+
729
+ #### Static Functions <a name="Static Functions" id="Static Functions"></a>
730
+
731
+ | **Name** | **Description** |
732
+ | --- | --- |
733
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstance.isConstruct">isConstruct</a></code> | Checks if `x` is a construct. |
734
+
735
+ ---
736
+
737
+ ##### `isConstruct` <a name="isConstruct" id="@raindancers/raindancers-crew.RemoteCrewInstance.isConstruct"></a>
738
+
739
+ ```typescript
740
+ import { RemoteCrewInstance } from '@raindancers/raindancers-crew'
741
+
742
+ RemoteCrewInstance.isConstruct(x: any)
743
+ ```
744
+
745
+ Checks if `x` is a construct.
746
+
747
+ Use this method instead of `instanceof` to properly detect `Construct`
748
+ instances, even when the construct library is symlinked.
749
+
750
+ Explanation: in JavaScript, multiple copies of the `constructs` library on
751
+ disk are seen as independent, completely different libraries. As a
752
+ consequence, the class `Construct` in each copy of the `constructs` library
753
+ is seen as a different class, and an instance of one class will not test as
754
+ `instanceof` the other class. `npm install` will not create installations
755
+ like this, but users may manually symlink construct libraries together or
756
+ use a monorepo tool: in those cases, multiple copies of the `constructs`
757
+ library can be accidentally installed, and `instanceof` will behave
758
+ unpredictably. It is safest to avoid using `instanceof`, and using
759
+ this type-testing method instead.
760
+
761
+ ###### `x`<sup>Required</sup> <a name="x" id="@raindancers/raindancers-crew.RemoteCrewInstance.isConstruct.parameter.x"></a>
762
+
763
+ - *Type:* any
764
+
765
+ Any object.
766
+
767
+ ---
768
+
769
+ #### Properties <a name="Properties" id="Properties"></a>
770
+
771
+ | **Name** | **Type** | **Description** |
772
+ | --- | --- | --- |
773
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstance.property.node">node</a></code> | <code>constructs.Node</code> | The tree node. |
774
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstance.property.instance">instance</a></code> | <code>aws-cdk-lib.aws_ec2.Instance</code> | The EC2 instance (SSM target). |
775
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstance.property.instanceId">instanceId</a></code> | <code>string</code> | Instance id — the SSM target. |
776
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstance.property.publicDnsName">publicDnsName</a></code> | <code>string</code> | Public DNS of the instance (diagnostics only; |
777
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstance.property.role">role</a></code> | <code>aws-cdk-lib.aws_iam.Role</code> | The instance's IAM role (carries the permissions boundary). |
778
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstance.property.securityGroup">securityGroup</a></code> | <code>aws-cdk-lib.aws_ec2.SecurityGroup</code> | The SSM-only security group (no inbound unless allowSshCidr is set). |
779
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstance.property.stackTag">stackTag</a></code> | <code>string</code> | The discovery tag value written as `kirocrew:instance`. |
780
+
781
+ ---
782
+
783
+ ##### `node`<sup>Required</sup> <a name="node" id="@raindancers/raindancers-crew.RemoteCrewInstance.property.node"></a>
784
+
785
+ ```typescript
786
+ public readonly node: Node;
787
+ ```
788
+
789
+ - *Type:* constructs.Node
790
+
791
+ The tree node.
792
+
793
+ ---
794
+
795
+ ##### `instance`<sup>Required</sup> <a name="instance" id="@raindancers/raindancers-crew.RemoteCrewInstance.property.instance"></a>
796
+
797
+ ```typescript
798
+ public readonly instance: Instance;
799
+ ```
800
+
801
+ - *Type:* aws-cdk-lib.aws_ec2.Instance
802
+
803
+ The EC2 instance (SSM target).
804
+
805
+ ---
806
+
807
+ ##### `instanceId`<sup>Required</sup> <a name="instanceId" id="@raindancers/raindancers-crew.RemoteCrewInstance.property.instanceId"></a>
808
+
809
+ ```typescript
810
+ public readonly instanceId: string;
811
+ ```
812
+
813
+ - *Type:* string
814
+
815
+ Instance id — the SSM target.
816
+
817
+ ---
818
+
819
+ ##### `publicDnsName`<sup>Required</sup> <a name="publicDnsName" id="@raindancers/raindancers-crew.RemoteCrewInstance.property.publicDnsName"></a>
820
+
821
+ ```typescript
822
+ public readonly publicDnsName: string;
823
+ ```
824
+
825
+ - *Type:* string
826
+
827
+ Public DNS of the instance (diagnostics only;
828
+
829
+ access is via SSM).
830
+
831
+ ---
832
+
833
+ ##### `role`<sup>Required</sup> <a name="role" id="@raindancers/raindancers-crew.RemoteCrewInstance.property.role"></a>
834
+
835
+ ```typescript
836
+ public readonly role: Role;
837
+ ```
838
+
839
+ - *Type:* aws-cdk-lib.aws_iam.Role
840
+
841
+ The instance's IAM role (carries the permissions boundary).
842
+
843
+ ---
844
+
845
+ ##### `securityGroup`<sup>Required</sup> <a name="securityGroup" id="@raindancers/raindancers-crew.RemoteCrewInstance.property.securityGroup"></a>
846
+
847
+ ```typescript
848
+ public readonly securityGroup: SecurityGroup;
849
+ ```
850
+
851
+ - *Type:* aws-cdk-lib.aws_ec2.SecurityGroup
852
+
853
+ The SSM-only security group (no inbound unless allowSshCidr is set).
854
+
855
+ ---
856
+
857
+ ##### `stackTag`<sup>Required</sup> <a name="stackTag" id="@raindancers/raindancers-crew.RemoteCrewInstance.property.stackTag"></a>
858
+
859
+ ```typescript
860
+ public readonly stackTag: string;
861
+ ```
862
+
863
+ - *Type:* string
864
+
865
+ The discovery tag value written as `kirocrew:instance`.
866
+
867
+ ---
868
+
869
+
870
+ ## Structs <a name="Structs" id="Structs"></a>
871
+
872
+ ### CrewBackupBucketProps <a name="CrewBackupBucketProps" id="@raindancers/raindancers-crew.CrewBackupBucketProps"></a>
873
+
874
+ Properties for {@link CrewBackupBucket}.
875
+
876
+ #### Initializer <a name="Initializer" id="@raindancers/raindancers-crew.CrewBackupBucketProps.Initializer"></a>
877
+
878
+ ```typescript
879
+ import { CrewBackupBucketProps } from '@raindancers/raindancers-crew'
880
+
881
+ const crewBackupBucketProps: CrewBackupBucketProps = { ... }
882
+ ```
883
+
884
+ #### Properties <a name="Properties" id="Properties"></a>
885
+
886
+ | **Name** | **Type** | **Description** |
887
+ | --- | --- | --- |
888
+ | <code><a href="#@raindancers/raindancers-crew.CrewBackupBucketProps.property.bucketName">bucketName</a></code> | <code>string</code> | Explicit bucket name. |
889
+ | <code><a href="#@raindancers/raindancers-crew.CrewBackupBucketProps.property.noncurrentVersionExpirationDays">noncurrentVersionExpirationDays</a></code> | <code>number</code> | Days after which a NONCURRENT snapshot version is expired. |
890
+ | <code><a href="#@raindancers/raindancers-crew.CrewBackupBucketProps.property.removalPolicy">removalPolicy</a></code> | <code>aws-cdk-lib.RemovalPolicy</code> | What happens to the bucket when the stack is destroyed. |
891
+
892
+ ---
893
+
894
+ ##### `bucketName`<sup>Optional</sup> <a name="bucketName" id="@raindancers/raindancers-crew.CrewBackupBucketProps.property.bucketName"></a>
895
+
896
+ ```typescript
897
+ public readonly bucketName: string;
898
+ ```
899
+
900
+ - *Type:* string
901
+ - *Default:* CloudFormation-generated
902
+
903
+ Explicit bucket name.
904
+
905
+ Omit to let CloudFormation generate one.
906
+
907
+ ---
908
+
909
+ ##### `noncurrentVersionExpirationDays`<sup>Optional</sup> <a name="noncurrentVersionExpirationDays" id="@raindancers/raindancers-crew.CrewBackupBucketProps.property.noncurrentVersionExpirationDays"></a>
910
+
911
+ ```typescript
912
+ public readonly noncurrentVersionExpirationDays: number;
913
+ ```
914
+
915
+ - *Type:* number
916
+ - *Default:* 90
917
+
918
+ Days after which a NONCURRENT snapshot version is expired.
919
+
920
+ Current
921
+ versions are always kept. Set 0 to keep all versions forever.
922
+
923
+ ---
924
+
925
+ ##### `removalPolicy`<sup>Optional</sup> <a name="removalPolicy" id="@raindancers/raindancers-crew.CrewBackupBucketProps.property.removalPolicy"></a>
926
+
927
+ ```typescript
928
+ public readonly removalPolicy: RemovalPolicy;
929
+ ```
930
+
931
+ - *Type:* aws-cdk-lib.RemovalPolicy
932
+ - *Default:* RemovalPolicy.RETAIN
933
+
934
+ What happens to the bucket when the stack is destroyed.
935
+
936
+ Defaults to
937
+ RETAIN — the whole point is that the crew's learnings outlive the
938
+ instance, so the backup must outlive a stack teardown too.
939
+
940
+ ---
941
+
942
+ ### CrewRuntime <a name="CrewRuntime" id="@raindancers/raindancers-crew.CrewRuntime"></a>
943
+
944
+ Always-on runtime settings for the hosted crew, threaded into the crew `config.json` at boot. All fields are optional and default to the current gateway behaviour; omitting {@link RemoteCrewInstanceProps.crewRuntime} entirely reproduces today's `kirocrew setup --agent-only` + `kirocrew gateway` exactly.
945
+
946
+ Verified against KiroCrew v0.6.0: autopilot maps to `agent.approval_mode`,
947
+ idle-close maps to `session.timeout_secs`, and the conductor roster ships
948
+ with `setup --agent-only` (custom members are source-delivered JSON under
949
+ `~/.kiro/agents/`).
950
+
951
+ #### Initializer <a name="Initializer" id="@raindancers/raindancers-crew.CrewRuntime.Initializer"></a>
952
+
953
+ ```typescript
954
+ import { CrewRuntime } from '@raindancers/raindancers-crew'
955
+
956
+ const crewRuntime: CrewRuntime = { ... }
957
+ ```
958
+
959
+ #### Properties <a name="Properties" id="Properties"></a>
960
+
961
+ | **Name** | **Type** | **Description** |
962
+ | --- | --- | --- |
963
+ | <code><a href="#@raindancers/raindancers-crew.CrewRuntime.property.autopilot">autopilot</a></code> | <code>boolean</code> | Enable Autopilot: the hosted crew auto-approves tool calls that pass its security checks (deny rules and sensitive-path blocks still apply). |
964
+ | <code><a href="#@raindancers/raindancers-crew.CrewRuntime.property.disableIdleClose">disableIdleClose</a></code> | <code>boolean</code> | Keep the 24/7 brain session alive between events by disabling the idle session sweep. |
965
+
966
+ ---
967
+
968
+ ##### `autopilot`<sup>Optional</sup> <a name="autopilot" id="@raindancers/raindancers-crew.CrewRuntime.property.autopilot"></a>
969
+
970
+ ```typescript
971
+ public readonly autopilot: boolean;
972
+ ```
973
+
974
+ - *Type:* boolean
975
+ - *Default:* false (interactive; gateway default)
976
+
977
+ Enable Autopilot: the hosted crew auto-approves tool calls that pass its security checks (deny rules and sensitive-path blocks still apply).
978
+
979
+ Sets
980
+ `agent.approval_mode` to `"auto"` in config.json.
981
+
982
+ ---
983
+
984
+ ##### `disableIdleClose`<sup>Optional</sup> <a name="disableIdleClose" id="@raindancers/raindancers-crew.CrewRuntime.property.disableIdleClose"></a>
985
+
986
+ ```typescript
987
+ public readonly disableIdleClose: boolean;
988
+ ```
989
+
990
+ - *Type:* boolean
991
+ - *Default:* false (default 3600s idle timeout applies)
992
+
993
+ Keep the 24/7 brain session alive between events by disabling the idle session sweep.
994
+
995
+ Sets `session.timeout_secs` to `0` (documented: "0 disables
996
+ the idle sweep").
997
+
998
+ ---
999
+
1000
+ ### CrewSource <a name="CrewSource" id="@raindancers/raindancers-crew.CrewSource"></a>
1001
+
1002
+ How the KiroCrew source is delivered to the instance at first boot.
1003
+
1004
+ Exactly one mode is active. When {@link sourceBucket} is set the instance
1005
+ downloads a source tarball from S3 (and is granted read on just that one
1006
+ object); otherwise it shallow-clones {@link kirocrewRef} from
1007
+ {@link kirocrewRepo}.
1008
+
1009
+ #### Initializer <a name="Initializer" id="@raindancers/raindancers-crew.CrewSource.Initializer"></a>
1010
+
1011
+ ```typescript
1012
+ import { CrewSource } from '@raindancers/raindancers-crew'
1013
+
1014
+ const crewSource: CrewSource = { ... }
1015
+ ```
1016
+
1017
+ #### Properties <a name="Properties" id="Properties"></a>
1018
+
1019
+ | **Name** | **Type** | **Description** |
1020
+ | --- | --- | --- |
1021
+ | <code><a href="#@raindancers/raindancers-crew.CrewSource.property.kirocrewRef">kirocrewRef</a></code> | <code>string</code> | Git ref (branch or tag) to install when cloning. |
1022
+ | <code><a href="#@raindancers/raindancers-crew.CrewSource.property.kirocrewRepo">kirocrewRepo</a></code> | <code>string</code> | Git repository to clone when no S3 source is configured. |
1023
+ | <code><a href="#@raindancers/raindancers-crew.CrewSource.property.sourceBucket">sourceBucket</a></code> | <code>string</code> | S3 bucket holding the source tarball (`kirocrew-src.tar.gz`). When set, the instance role is granted `s3:GetObject` on this object ONLY. Leave unset to clone from git instead. |
1024
+ | <code><a href="#@raindancers/raindancers-crew.CrewSource.property.sourceKey">sourceKey</a></code> | <code>string</code> | S3 key of the source tarball within {@link sourceBucket}. |
1025
+
1026
+ ---
1027
+
1028
+ ##### `kirocrewRef`<sup>Optional</sup> <a name="kirocrewRef" id="@raindancers/raindancers-crew.CrewSource.property.kirocrewRef"></a>
1029
+
1030
+ ```typescript
1031
+ public readonly kirocrewRef: string;
1032
+ ```
1033
+
1034
+ - *Type:* string
1035
+ - *Default:* 'main'
1036
+
1037
+ Git ref (branch or tag) to install when cloning.
1038
+
1039
+ Pin this to a released tag for reproducible, version-controlled deploys —
1040
+ the upstream launcher defaults to `main`, which drifts. This construct
1041
+ defaults to `main` only to match upstream; SET IT to a tag in production.
1042
+
1043
+ ---
1044
+
1045
+ ##### `kirocrewRepo`<sup>Optional</sup> <a name="kirocrewRepo" id="@raindancers/raindancers-crew.CrewSource.property.kirocrewRepo"></a>
1046
+
1047
+ ```typescript
1048
+ public readonly kirocrewRepo: string;
1049
+ ```
1050
+
1051
+ - *Type:* string
1052
+ - *Default:* 'https://github.com/kirodotdev/KiroCrew.git'
1053
+
1054
+ Git repository to clone when no S3 source is configured.
1055
+
1056
+ ---
1057
+
1058
+ ##### `sourceBucket`<sup>Optional</sup> <a name="sourceBucket" id="@raindancers/raindancers-crew.CrewSource.property.sourceBucket"></a>
1059
+
1060
+ ```typescript
1061
+ public readonly sourceBucket: string;
1062
+ ```
1063
+
1064
+ - *Type:* string
1065
+ - *Default:* clone from git (see kirocrewRepo / kirocrewRef)
1066
+
1067
+ S3 bucket holding the source tarball (`kirocrew-src.tar.gz`). When set, the instance role is granted `s3:GetObject` on this object ONLY. Leave unset to clone from git instead.
1068
+
1069
+ ---
1070
+
1071
+ ##### `sourceKey`<sup>Optional</sup> <a name="sourceKey" id="@raindancers/raindancers-crew.CrewSource.property.sourceKey"></a>
1072
+
1073
+ ```typescript
1074
+ public readonly sourceKey: string;
1075
+ ```
1076
+
1077
+ - *Type:* string
1078
+ - *Default:* none
1079
+
1080
+ S3 key of the source tarball within {@link sourceBucket}.
1081
+
1082
+ Required when
1083
+ `sourceBucket` is set; ignored otherwise.
1084
+
1085
+ ---
1086
+
1087
+ ### FargateCrewBaseProps <a name="FargateCrewBaseProps" id="@raindancers/raindancers-crew.FargateCrewBaseProps"></a>
1088
+
1089
+ Properties for {@link FargateCrewBase}.
1090
+
1091
+ #### Initializer <a name="Initializer" id="@raindancers/raindancers-crew.FargateCrewBaseProps.Initializer"></a>
1092
+
1093
+ ```typescript
1094
+ import { FargateCrewBaseProps } from '@raindancers/raindancers-crew'
1095
+
1096
+ const fargateCrewBaseProps: FargateCrewBaseProps = { ... }
1097
+ ```
1098
+
1099
+ #### Properties <a name="Properties" id="Properties"></a>
1100
+
1101
+ | **Name** | **Type** | **Description** |
1102
+ | --- | --- | --- |
1103
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrewBaseProps.property.vpc">vpc</a></code> | <code>aws-cdk-lib.aws_ec2.IVpc</code> | VPC the crew tasks are placed in. |
1104
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrewBaseProps.property.cpuArchitecture">cpuArchitecture</a></code> | <code><a href="#@raindancers/raindancers-crew.FargateCpuArchitecture">FargateCpuArchitecture</a></code> | Architecture the crew image was built for. |
1105
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrewBaseProps.property.stackTag">stackTag</a></code> | <code>string</code> | Discovery tag value written as `kirocrew:fargate`. |
1106
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrewBaseProps.property.vpcSubnets">vpcSubnets</a></code> | <code>aws-cdk-lib.aws_ec2.SubnetSelection</code> | Subnets for the tasks' awsvpc network interfaces. |
1107
+
1108
+ ---
1109
+
1110
+ ##### `vpc`<sup>Required</sup> <a name="vpc" id="@raindancers/raindancers-crew.FargateCrewBaseProps.property.vpc"></a>
1111
+
1112
+ ```typescript
1113
+ public readonly vpc: IVpc;
1114
+ ```
1115
+
1116
+ - *Type:* aws-cdk-lib.aws_ec2.IVpc
1117
+
1118
+ VPC the crew tasks are placed in.
1119
+
1120
+ ---
1121
+
1122
+ ##### `cpuArchitecture`<sup>Optional</sup> <a name="cpuArchitecture" id="@raindancers/raindancers-crew.FargateCrewBaseProps.property.cpuArchitecture"></a>
1123
+
1124
+ ```typescript
1125
+ public readonly cpuArchitecture: FargateCpuArchitecture;
1126
+ ```
1127
+
1128
+ - *Type:* <a href="#@raindancers/raindancers-crew.FargateCpuArchitecture">FargateCpuArchitecture</a>
1129
+ - *Default:* FargateCpuArchitecture.X86_64
1130
+
1131
+ Architecture the crew image was built for.
1132
+
1133
+ Surfaced as an output for the
1134
+ launch spec so every placement field is read from a stack, not the
1135
+ operator's memory.
1136
+
1137
+ ---
1138
+
1139
+ ##### `stackTag`<sup>Optional</sup> <a name="stackTag" id="@raindancers/raindancers-crew.FargateCrewBaseProps.property.stackTag"></a>
1140
+
1141
+ ```typescript
1142
+ public readonly stackTag: string;
1143
+ ```
1144
+
1145
+ - *Type:* string
1146
+ - *Default:* 'kirocrew'
1147
+
1148
+ Discovery tag value written as `kirocrew:fargate`.
1149
+
1150
+ Must match
1151
+ `[a-zA-Z0-9-]{1,51}`. The cluster is named `kirocrew-crew-<stackTag>`.
1152
+
1153
+ ---
1154
+
1155
+ ##### `vpcSubnets`<sup>Optional</sup> <a name="vpcSubnets" id="@raindancers/raindancers-crew.FargateCrewBaseProps.property.vpcSubnets"></a>
1156
+
1157
+ ```typescript
1158
+ public readonly vpcSubnets: SubnetSelection;
1159
+ ```
1160
+
1161
+ - *Type:* aws-cdk-lib.aws_ec2.SubnetSelection
1162
+ - *Default:* the VPC's private-with-egress subnets
1163
+
1164
+ Subnets for the tasks' awsvpc network interfaces.
1165
+
1166
+ Each must be able to
1167
+ reach the container registry — a NAT-routed private subnet, or a public
1168
+ subnet with `assignPublicIp` at RunTask.
1169
+
1170
+ Networking is taken, never invented: whether egress is via NAT or a public
1171
+ subnet is a property of the operator's VPC this construct cannot discover,
1172
+ so it is passed in and echoed as an output for the launch spec.
1173
+
1174
+ ---
1175
+
1176
+ ### FargateCrewProps <a name="FargateCrewProps" id="@raindancers/raindancers-crew.FargateCrewProps"></a>
1177
+
1178
+ Properties for {@link FargateCrew}.
1179
+
1180
+ #### Initializer <a name="Initializer" id="@raindancers/raindancers-crew.FargateCrewProps.Initializer"></a>
1181
+
1182
+ ```typescript
1183
+ import { FargateCrewProps } from '@raindancers/raindancers-crew'
1184
+
1185
+ const fargateCrewProps: FargateCrewProps = { ... }
1186
+ ```
1187
+
1188
+ #### Properties <a name="Properties" id="Properties"></a>
1189
+
1190
+ | **Name** | **Type** | **Description** |
1191
+ | --- | --- | --- |
1192
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrewProps.property.crew">crew</a></code> | <code>string</code> | Crew name: 1–32 chars, lower-case alphanumeric with inner hyphens, never leading or trailing. |
1193
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrewProps.property.backupBucket">backupBucket</a></code> | <code><a href="#@raindancers/raindancers-crew.ICrewBackupBucket">ICrewBackupBucket</a></code> | An S3 backup bucket to grant the TASK role write access to, so the running crew container can push `kirocrew snapshot` bundles off-box on its own schedule. |
1194
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrewProps.property.ecrRepositoryArn">ecrRepositoryArn</a></code> | <code>string</code> | ARN of the private ECR repository holding the crew image. |
1195
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrewProps.property.logRetentionDays">logRetentionDays</a></code> | <code>number</code> | Days a crew's task logs are kept before CloudWatch expires them. |
1196
+ | <code><a href="#@raindancers/raindancers-crew.FargateCrewProps.property.permissionsBoundaryArn">permissionsBoundaryArn</a></code> | <code>string</code> | ARN of the pre-created shared crew permissions boundary (`arn:aws:iam::<account>:policy/kirocrew-crew-boundary`). |
1197
+
1198
+ ---
1199
+
1200
+ ##### `crew`<sup>Required</sup> <a name="crew" id="@raindancers/raindancers-crew.FargateCrewProps.property.crew"></a>
1201
+
1202
+ ```typescript
1203
+ public readonly crew: string;
1204
+ ```
1205
+
1206
+ - *Type:* string
1207
+
1208
+ Crew name: 1–32 chars, lower-case alphanumeric with inner hyphens, never leading or trailing.
1209
+
1210
+ Every resource name is DERIVED from it — the task
1211
+ definition rebuilds the role ARNs and log-group name from the crew name
1212
+ and refuses a document whose ARNs disagree, so a rename here is a launch
1213
+ refusal, not a silent mismatch.
1214
+
1215
+ ---
1216
+
1217
+ ##### `backupBucket`<sup>Optional</sup> <a name="backupBucket" id="@raindancers/raindancers-crew.FargateCrewProps.property.backupBucket"></a>
1218
+
1219
+ ```typescript
1220
+ public readonly backupBucket: ICrewBackupBucket;
1221
+ ```
1222
+
1223
+ - *Type:* <a href="#@raindancers/raindancers-crew.ICrewBackupBucket">ICrewBackupBucket</a>
1224
+ - *Default:* no off-box backup grant
1225
+
1226
+ An S3 backup bucket to grant the TASK role write access to, so the running crew container can push `kirocrew snapshot` bundles off-box on its own schedule.
1227
+
1228
+ The task role (not the execution role) gets this, because the
1229
+ push runs inside the container. Omit to disable off-box backup.
1230
+
1231
+ ---
1232
+
1233
+ ##### `ecrRepositoryArn`<sup>Optional</sup> <a name="ecrRepositoryArn" id="@raindancers/raindancers-crew.FargateCrewProps.property.ecrRepositoryArn"></a>
1234
+
1235
+ ```typescript
1236
+ public readonly ecrRepositoryArn: string;
1237
+ ```
1238
+
1239
+ - *Type:* string
1240
+ - *Default:* public registry; no pull grant
1241
+
1242
+ ARN of the private ECR repository holding the crew image.
1243
+
1244
+ Leave unset when
1245
+ the image is pulled from a public registry (the decided delivery, ECR
1246
+ Public), which needs no execution-role pull grant. When set, the pull grant
1247
+ is scoped to this one repository.
1248
+
1249
+ ---
1250
+
1251
+ ##### `logRetentionDays`<sup>Optional</sup> <a name="logRetentionDays" id="@raindancers/raindancers-crew.FargateCrewProps.property.logRetentionDays"></a>
1252
+
1253
+ ```typescript
1254
+ public readonly logRetentionDays: number;
1255
+ ```
1256
+
1257
+ - *Type:* number
1258
+ - *Default:* 30
1259
+
1260
+ Days a crew's task logs are kept before CloudWatch expires them.
1261
+
1262
+ Must be
1263
+ one of the CloudWatch retention values.
1264
+
1265
+ ---
1266
+
1267
+ ##### `permissionsBoundaryArn`<sup>Optional</sup> <a name="permissionsBoundaryArn" id="@raindancers/raindancers-crew.FargateCrewProps.property.permissionsBoundaryArn"></a>
1268
+
1269
+ ```typescript
1270
+ public readonly permissionsBoundaryArn: string;
1271
+ ```
1272
+
1273
+ - *Type:* string
1274
+ - *Default:* no boundary (declared degraded mode)
1275
+
1276
+ ARN of the pre-created shared crew permissions boundary (`arn:aws:iam::<account>:policy/kirocrew-crew-boundary`).
1277
+
1278
+ Optional by design: this is a DECLARED degraded mode. Unlike the EC2 lane
1279
+ (whose boundary is created once by launcher code), no creator exists for
1280
+ the crew boundary yet, so rather than reference a policy nothing creates
1281
+ this is omitted until that creator lands. When set, it caps what these
1282
+ roles can ever do regardless of attached policies.
1283
+
1284
+ ---
1285
+
1286
+ ### RemoteCrewInstanceProps <a name="RemoteCrewInstanceProps" id="@raindancers/raindancers-crew.RemoteCrewInstanceProps"></a>
1287
+
1288
+ Properties for {@link RemoteCrewInstance }.
1289
+
1290
+ #### Initializer <a name="Initializer" id="@raindancers/raindancers-crew.RemoteCrewInstanceProps.Initializer"></a>
1291
+
1292
+ ```typescript
1293
+ import { RemoteCrewInstanceProps } from '@raindancers/raindancers-crew'
1294
+
1295
+ const remoteCrewInstanceProps: RemoteCrewInstanceProps = { ... }
1296
+ ```
1297
+
1298
+ #### Properties <a name="Properties" id="Properties"></a>
1299
+
1300
+ | **Name** | **Type** | **Description** |
1301
+ | --- | --- | --- |
1302
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.permissionsBoundaryArn">permissionsBoundaryArn</a></code> | <code>string</code> | ARN of an IAM permissions boundary applied to the instance role. |
1303
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.vpc">vpc</a></code> | <code>aws-cdk-lib.aws_ec2.IVpc</code> | VPC to launch the instance into. |
1304
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.allowSshCidr">allowSshCidr</a></code> | <code>string</code> | Optional SSH ingress CIDR. |
1305
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.architecture">architecture</a></code> | <code><a href="#@raindancers/raindancers-crew.CrewArchitecture">CrewArchitecture</a></code> | CPU architecture. |
1306
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.associatePublicIp">associatePublicIp</a></code> | <code>boolean</code> | Attach a public IP to the instance ENI. |
1307
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.backupBucket">backupBucket</a></code> | <code><a href="#@raindancers/raindancers-crew.ICrewBackupBucket">ICrewBackupBucket</a></code> | An S3 backup bucket to push crew snapshots to on a schedule. |
1308
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.backupPrefix">backupPrefix</a></code> | <code>string</code> | S3 key prefix under which snapshots are stored in the backup bucket. |
1309
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.backupSchedule">backupSchedule</a></code> | <code>string</code> | systemd OnCalendar expression for the backup timer (see `man systemd.time`). Only used when {@link backupBucket} is set. |
1310
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.bootstrapTimeoutMinutes">bootstrapTimeoutMinutes</a></code> | <code>number</code> | Minutes to wait for the gateway to become healthy before the stack fails and rolls back (cold boot + dnf + Node + vite build + pip). |
1311
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.crewRuntime">crewRuntime</a></code> | <code><a href="#@raindancers/raindancers-crew.CrewRuntime">CrewRuntime</a></code> | Always-on runtime settings (Autopilot, no-idle-close) for the hosted crew, threaded into config.json at boot. Omit for the current gateway defaults. |
1312
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.dashboardPort">dashboardPort</a></code> | <code>number</code> | TCP port the gateway serves the dashboard on (loopback only; |
1313
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.enableIpv6">enableIpv6</a></code> | <code>boolean</code> | Assign an IPv6 address to the instance's primary ENI and permit IPv6 egress on the security group. |
1314
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.instanceType">instanceType</a></code> | <code>aws-cdk-lib.aws_ec2.InstanceType</code> | EC2 instance type. |
1315
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.source">source</a></code> | <code><a href="#@raindancers/raindancers-crew.CrewSource">CrewSource</a></code> | How the KiroCrew source reaches the instance (S3 tarball or git clone). |
1316
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.stackTag">stackTag</a></code> | <code>string</code> | Discovery tag value written as `kirocrew:instance`. |
1317
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.volumeSizeGb">volumeSizeGb</a></code> | <code>number</code> | gp3 root volume size in GiB (20–1000). |
1318
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.vpcSubnets">vpcSubnets</a></code> | <code>aws-cdk-lib.aws_ec2.SubnetSelection</code> | Subnet selection for the instance. |
1319
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.webhookIngress">webhookIngress</a></code> | <code><a href="#@raindancers/raindancers-crew.WebhookIngress">WebhookIngress</a></code> | Open the gateway/webhook port to ONE source security group only (never a CIDR). |
1320
+ | <code><a href="#@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.webhookTokenSecretArn">webhookTokenSecretArn</a></code> | <code>string</code> | Secrets Manager ARN of the Bearer token that authenticates the native webhook (`POST /api/hooks/agent`). |
1321
+
1322
+ ---
1323
+
1324
+ ##### `permissionsBoundaryArn`<sup>Required</sup> <a name="permissionsBoundaryArn" id="@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.permissionsBoundaryArn"></a>
1325
+
1326
+ ```typescript
1327
+ public readonly permissionsBoundaryArn: string;
1328
+ ```
1329
+
1330
+ - *Type:* string
1331
+
1332
+ ARN of an IAM permissions boundary applied to the instance role.
1333
+
1334
+ The instance runs a prompt-injectable agent that executes arbitrary
1335
+ tools, so its role MUST carry a boundary that caps blast radius. This is
1336
+ required, not optional.
1337
+
1338
+ ---
1339
+
1340
+ ##### `vpc`<sup>Required</sup> <a name="vpc" id="@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.vpc"></a>
1341
+
1342
+ ```typescript
1343
+ public readonly vpc: IVpc;
1344
+ ```
1345
+
1346
+ - *Type:* aws-cdk-lib.aws_ec2.IVpc
1347
+
1348
+ VPC to launch the instance into.
1349
+
1350
+ ---
1351
+
1352
+ ##### `allowSshCidr`<sup>Optional</sup> <a name="allowSshCidr" id="@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.allowSshCidr"></a>
1353
+
1354
+ ```typescript
1355
+ public readonly allowSshCidr: string;
1356
+ ```
1357
+
1358
+ - *Type:* string
1359
+ - *Default:* no inbound; SSM-only
1360
+
1361
+ Optional SSH ingress CIDR.
1362
+
1363
+ When set (and no wider than /16), opens tcp/22
1364
+ from that CIDR as a fallback. Omit for SSM-only access (recommended).
1365
+
1366
+ ---
1367
+
1368
+ ##### `architecture`<sup>Optional</sup> <a name="architecture" id="@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.architecture"></a>
1369
+
1370
+ ```typescript
1371
+ public readonly architecture: CrewArchitecture;
1372
+ ```
1373
+
1374
+ - *Type:* <a href="#@raindancers/raindancers-crew.CrewArchitecture">CrewArchitecture</a>
1375
+ - *Default:* CrewArchitecture.ARM64
1376
+
1377
+ CPU architecture.
1378
+
1379
+ Must match {@link instanceType} when that is set.
1380
+
1381
+ ---
1382
+
1383
+ ##### `associatePublicIp`<sup>Optional</sup> <a name="associatePublicIp" id="@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.associatePublicIp"></a>
1384
+
1385
+ ```typescript
1386
+ public readonly associatePublicIp: boolean;
1387
+ ```
1388
+
1389
+ - *Type:* boolean
1390
+ - *Default:* true
1391
+
1392
+ Attach a public IP to the instance ENI.
1393
+
1394
+ Required for egress on IGW-only
1395
+ subnets; leave off (false) for NAT-routed private subnets, where it is
1396
+ unused attack surface.
1397
+
1398
+ ---
1399
+
1400
+ ##### `backupBucket`<sup>Optional</sup> <a name="backupBucket" id="@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.backupBucket"></a>
1401
+
1402
+ ```typescript
1403
+ public readonly backupBucket: ICrewBackupBucket;
1404
+ ```
1405
+
1406
+ - *Type:* <a href="#@raindancers/raindancers-crew.ICrewBackupBucket">ICrewBackupBucket</a>
1407
+ - *Default:* no off-box backup
1408
+
1409
+ An S3 backup bucket to push crew snapshots to on a schedule.
1410
+
1411
+ When set, the
1412
+ instance role is granted write, a systemd timer runs
1413
+ `kirocrew snapshot --purpose backup` and uploads the newest (redaction-
1414
+ scrubbed) bundle, and a `kirocrew-restore-from-s3` helper is installed for
1415
+ rebuilding a replacement instance. Omit to disable off-box backup.
1416
+
1417
+ ---
1418
+
1419
+ ##### `backupPrefix`<sup>Optional</sup> <a name="backupPrefix" id="@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.backupPrefix"></a>
1420
+
1421
+ ```typescript
1422
+ public readonly backupPrefix: string;
1423
+ ```
1424
+
1425
+ - *Type:* string
1426
+ - *Default:* 'crew-snapshots/'
1427
+
1428
+ S3 key prefix under which snapshots are stored in the backup bucket.
1429
+
1430
+ Only used when {@link backupBucket} is set. A trailing slash is added if
1431
+ absent.
1432
+
1433
+ ---
1434
+
1435
+ ##### `backupSchedule`<sup>Optional</sup> <a name="backupSchedule" id="@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.backupSchedule"></a>
1436
+
1437
+ ```typescript
1438
+ public readonly backupSchedule: string;
1439
+ ```
1440
+
1441
+ - *Type:* string
1442
+ - *Default:* 'daily'
1443
+
1444
+ systemd OnCalendar expression for the backup timer (see `man systemd.time`). Only used when {@link backupBucket} is set.
1445
+
1446
+ ---
1447
+
1448
+ ##### `bootstrapTimeoutMinutes`<sup>Optional</sup> <a name="bootstrapTimeoutMinutes" id="@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.bootstrapTimeoutMinutes"></a>
1449
+
1450
+ ```typescript
1451
+ public readonly bootstrapTimeoutMinutes: number;
1452
+ ```
1453
+
1454
+ - *Type:* number
1455
+ - *Default:* 25
1456
+
1457
+ Minutes to wait for the gateway to become healthy before the stack fails and rolls back (cold boot + dnf + Node + vite build + pip).
1458
+
1459
+ ---
1460
+
1461
+ ##### `crewRuntime`<sup>Optional</sup> <a name="crewRuntime" id="@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.crewRuntime"></a>
1462
+
1463
+ ```typescript
1464
+ public readonly crewRuntime: CrewRuntime;
1465
+ ```
1466
+
1467
+ - *Type:* <a href="#@raindancers/raindancers-crew.CrewRuntime">CrewRuntime</a>
1468
+ - *Default:* current gateway behaviour (interactive, 3600s idle timeout)
1469
+
1470
+ Always-on runtime settings (Autopilot, no-idle-close) for the hosted crew, threaded into config.json at boot. Omit for the current gateway defaults.
1471
+
1472
+ ---
1473
+
1474
+ ##### `dashboardPort`<sup>Optional</sup> <a name="dashboardPort" id="@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.dashboardPort"></a>
1475
+
1476
+ ```typescript
1477
+ public readonly dashboardPort: number;
1478
+ ```
1479
+
1480
+ - *Type:* number
1481
+ - *Default:* 5476
1482
+
1483
+ TCP port the gateway serves the dashboard on (loopback only;
1484
+
1485
+ reached via
1486
+ SSM port-forward). Recorded in the instance registry as the remote port.
1487
+
1488
+ ---
1489
+
1490
+ ##### `enableIpv6`<sup>Optional</sup> <a name="enableIpv6" id="@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.enableIpv6"></a>
1491
+
1492
+ ```typescript
1493
+ public readonly enableIpv6: boolean;
1494
+ ```
1495
+
1496
+ - *Type:* boolean
1497
+ - *Default:* false
1498
+
1499
+ Assign an IPv6 address to the instance's primary ENI and permit IPv6 egress on the security group.
1500
+
1501
+ Enables a dual-stack posture: combined with `associatePublicIp: false` and
1502
+ a private, IPv6-capable subnet, the instance egresses over IPv6 (via the
1503
+ VPC's Egress-Only Internet Gateway) with no public IPv4. CDK's
1504
+ `allowAllOutbound` renders IPv4 `0.0.0.0/0` egress only, so this also adds
1505
+ an explicit all-traffic IPv6 egress rule.
1506
+
1507
+ This construct does NOT provision subnet IPv6 CIDRs, an Egress-Only
1508
+ Internet Gateway, or any route — those are the consumer VPC's
1509
+ responsibility. The selected subnet(s) MUST already carry IPv6 CIDRs.
1510
+
1511
+ ---
1512
+
1513
+ ##### `instanceType`<sup>Optional</sup> <a name="instanceType" id="@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.instanceType"></a>
1514
+
1515
+ ```typescript
1516
+ public readonly instanceType: InstanceType;
1517
+ ```
1518
+
1519
+ - *Type:* aws-cdk-lib.aws_ec2.InstanceType
1520
+ - *Default:* m7g.2xlarge (arm64) / m7i.2xlarge (x86_64), matching the upstream "Development" size tier
1521
+
1522
+ EC2 instance type.
1523
+
1524
+ ---
1525
+
1526
+ ##### `source`<sup>Optional</sup> <a name="source" id="@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.source"></a>
1527
+
1528
+ ```typescript
1529
+ public readonly source: CrewSource;
1530
+ ```
1531
+
1532
+ - *Type:* <a href="#@raindancers/raindancers-crew.CrewSource">CrewSource</a>
1533
+ - *Default:* clone kirodotdev/KiroCrew@main
1534
+
1535
+ How the KiroCrew source reaches the instance (S3 tarball or git clone).
1536
+
1537
+ ---
1538
+
1539
+ ##### `stackTag`<sup>Optional</sup> <a name="stackTag" id="@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.stackTag"></a>
1540
+
1541
+ ```typescript
1542
+ public readonly stackTag: string;
1543
+ ```
1544
+
1545
+ - *Type:* string
1546
+ - *Default:* 'kirocrew'
1547
+
1548
+ Discovery tag value written as `kirocrew:instance`.
1549
+
1550
+ Must match
1551
+ `[a-zA-Z0-9-]{1,51}`.
1552
+
1553
+ ---
1554
+
1555
+ ##### `volumeSizeGb`<sup>Optional</sup> <a name="volumeSizeGb" id="@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.volumeSizeGb"></a>
1556
+
1557
+ ```typescript
1558
+ public readonly volumeSizeGb: number;
1559
+ ```
1560
+
1561
+ - *Type:* number
1562
+ - *Default:* 60
1563
+
1564
+ gp3 root volume size in GiB (20–1000).
1565
+
1566
+ The volume is always encrypted.
1567
+
1568
+ ---
1569
+
1570
+ ##### `vpcSubnets`<sup>Optional</sup> <a name="vpcSubnets" id="@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.vpcSubnets"></a>
1571
+
1572
+ ```typescript
1573
+ public readonly vpcSubnets: SubnetSelection;
1574
+ ```
1575
+
1576
+ - *Type:* aws-cdk-lib.aws_ec2.SubnetSelection
1577
+ - *Default:* one public subnet in the VPC
1578
+
1579
+ Subnet selection for the instance.
1580
+
1581
+ A public (IGW-routed) subnet needs a
1582
+ public IP for egress; a private (NAT-routed) subnet does not — see
1583
+ {@link associatePublicIp}.
1584
+
1585
+ ---
1586
+
1587
+ ##### `webhookIngress`<sup>Optional</sup> <a name="webhookIngress" id="@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.webhookIngress"></a>
1588
+
1589
+ ```typescript
1590
+ public readonly webhookIngress: WebhookIngress;
1591
+ ```
1592
+
1593
+ - *Type:* <a href="#@raindancers/raindancers-crew.WebhookIngress">WebhookIngress</a>
1594
+ - *Default:* no webhook ingress
1595
+
1596
+ Open the gateway/webhook port to ONE source security group only (never a CIDR).
1597
+
1598
+ Independent of {@link allowSshCidr} — both, either, or neither may
1599
+ be set; unset leaves the SG no-inbound (the default).
1600
+
1601
+ ---
1602
+
1603
+ ##### `webhookTokenSecretArn`<sup>Optional</sup> <a name="webhookTokenSecretArn" id="@raindancers/raindancers-crew.RemoteCrewInstanceProps.property.webhookTokenSecretArn"></a>
1604
+
1605
+ ```typescript
1606
+ public readonly webhookTokenSecretArn: string;
1607
+ ```
1608
+
1609
+ - *Type:* string
1610
+ - *Default:* webhook auth not configured (loopback / SSM only)
1611
+
1612
+ Secrets Manager ARN of the Bearer token that authenticates the native webhook (`POST /api/hooks/agent`).
1613
+
1614
+ At boot the instance fetches the secret
1615
+ and writes it as `hooks.webhook_token` in the crew `config.json` — the
1616
+ token is never baked into userData, env literals, or code. The instance
1617
+ role is granted `secretsmanager:GetSecretValue` on THIS ARN only.
1618
+
1619
+ Required when {@link webhookIngress} is set: a reachable webhook with no
1620
+ auth is a defect, not a default, so synth fails if ingress is opened
1621
+ without a token.
1622
+
1623
+ NOTE: the KiroCrew gateway binds loopback (`127.0.0.1`) only and exposes no
1624
+ routable webhook listener — see the webhook Decisions-for-review in the PR.
1625
+ This wires the AUTH (token-in-config); routable exposure of the loopback
1626
+ route is a consumer reverse-proxy / tunnel concern.
1627
+
1628
+ ---
1629
+
1630
+ ### WebhookIngress <a name="WebhookIngress" id="@raindancers/raindancers-crew.WebhookIngress"></a>
1631
+
1632
+ Exposes the gateway's webhook port to ONE source security group.
1633
+
1634
+ There is deliberately no CIDR form: the brain box is never internet-
1635
+ reachable by contract. The named source SG (e.g. an ingest Lambda's SG, or a
1636
+ reverse proxy that fronts the loopback gateway) is the only peer allowed to
1637
+ reach the port.
1638
+
1639
+ NOTE: the KiroCrew gateway binds loopback (`127.0.0.1`) only — it exposes no
1640
+ routable listener. This rule opens the security group so a consumer-owned
1641
+ reverse proxy / tunnel on the box can be reached from the source SG; actually
1642
+ serving the webhook on a routable interface is the consumer's concern (see
1643
+ README "Private dual-stack brain" and the webhook Decisions-for-review).
1644
+
1645
+ #### Initializer <a name="Initializer" id="@raindancers/raindancers-crew.WebhookIngress.Initializer"></a>
1646
+
1647
+ ```typescript
1648
+ import { WebhookIngress } from '@raindancers/raindancers-crew'
1649
+
1650
+ const webhookIngress: WebhookIngress = { ... }
1651
+ ```
1652
+
1653
+ #### Properties <a name="Properties" id="Properties"></a>
1654
+
1655
+ | **Name** | **Type** | **Description** |
1656
+ | --- | --- | --- |
1657
+ | <code><a href="#@raindancers/raindancers-crew.WebhookIngress.property.source">source</a></code> | <code>aws-cdk-lib.aws_ec2.ISecurityGroup</code> | Imported security group allowed to reach the webhook port. |
1658
+ | <code><a href="#@raindancers/raindancers-crew.WebhookIngress.property.port">port</a></code> | <code>number</code> | TCP port the ingress rule opens. |
1659
+
1660
+ ---
1661
+
1662
+ ##### `source`<sup>Required</sup> <a name="source" id="@raindancers/raindancers-crew.WebhookIngress.property.source"></a>
1663
+
1664
+ ```typescript
1665
+ public readonly source: ISecurityGroup;
1666
+ ```
1667
+
1668
+ - *Type:* aws-cdk-lib.aws_ec2.ISecurityGroup
1669
+
1670
+ Imported security group allowed to reach the webhook port.
1671
+
1672
+ Passed as an
1673
+ `ISecurityGroup` (imported) — this construct never creates it.
1674
+
1675
+ ---
1676
+
1677
+ ##### `port`<sup>Optional</sup> <a name="port" id="@raindancers/raindancers-crew.WebhookIngress.property.port"></a>
1678
+
1679
+ ```typescript
1680
+ public readonly port: number;
1681
+ ```
1682
+
1683
+ - *Type:* number
1684
+ - *Default:* the resolved dashboardPort (5476)
1685
+
1686
+ TCP port the ingress rule opens.
1687
+
1688
+ Defaults to the dashboard/gateway port so
1689
+ a reverse proxy fronting the loopback gateway is reachable; override to
1690
+ target a consumer proxy on a different port.
1691
+
1692
+ ---
1693
+
1694
+
1695
+ ## Protocols <a name="Protocols" id="Protocols"></a>
1696
+
1697
+ ### ICrewBackupBucket <a name="ICrewBackupBucket" id="@raindancers/raindancers-crew.ICrewBackupBucket"></a>
1698
+
1699
+ - *Implemented By:* <a href="#@raindancers/raindancers-crew.CrewBackupBucket">CrewBackupBucket</a>, <a href="#@raindancers/raindancers-crew.ICrewBackupBucket">ICrewBackupBucket</a>
1700
+
1701
+ The subset of {@link CrewBackupBucket } the EC2/Fargate constructs need.
1702
+
1703
+ Kept
1704
+ as an interface so a consumer can pass their own bucket wrapper.
1705
+
1706
+ #### Methods <a name="Methods" id="Methods"></a>
1707
+
1708
+ | **Name** | **Description** |
1709
+ | --- | --- |
1710
+ | <code><a href="#@raindancers/raindancers-crew.ICrewBackupBucket.grantRead">grantRead</a></code> | Grant a principal read access to snapshots (bucket + KMS). |
1711
+ | <code><a href="#@raindancers/raindancers-crew.ICrewBackupBucket.grantWrite">grantWrite</a></code> | Grant a principal write access to snapshots (bucket + KMS). |
1712
+
1713
+ ---
1714
+
1715
+ ##### `grantRead` <a name="grantRead" id="@raindancers/raindancers-crew.ICrewBackupBucket.grantRead"></a>
1716
+
1717
+ ```typescript
1718
+ public grantRead(grantee: IGrantable): void
1719
+ ```
1720
+
1721
+ Grant a principal read access to snapshots (bucket + KMS).
1722
+
1723
+ ###### `grantee`<sup>Required</sup> <a name="grantee" id="@raindancers/raindancers-crew.ICrewBackupBucket.grantRead.parameter.grantee"></a>
1724
+
1725
+ - *Type:* aws-cdk-lib.aws_iam.IGrantable
1726
+
1727
+ ---
1728
+
1729
+ ##### `grantWrite` <a name="grantWrite" id="@raindancers/raindancers-crew.ICrewBackupBucket.grantWrite"></a>
1730
+
1731
+ ```typescript
1732
+ public grantWrite(grantee: IGrantable): void
1733
+ ```
1734
+
1735
+ Grant a principal write access to snapshots (bucket + KMS).
1736
+
1737
+ ###### `grantee`<sup>Required</sup> <a name="grantee" id="@raindancers/raindancers-crew.ICrewBackupBucket.grantWrite.parameter.grantee"></a>
1738
+
1739
+ - *Type:* aws-cdk-lib.aws_iam.IGrantable
1740
+
1741
+ ---
1742
+
1743
+ #### Properties <a name="Properties" id="Properties"></a>
1744
+
1745
+ | **Name** | **Type** | **Description** |
1746
+ | --- | --- | --- |
1747
+ | <code><a href="#@raindancers/raindancers-crew.ICrewBackupBucket.property.bucket">bucket</a></code> | <code>aws-cdk-lib.aws_s3.IBucket</code> | The destination bucket name. |
1748
+
1749
+ ---
1750
+
1751
+ ##### `bucket`<sup>Required</sup> <a name="bucket" id="@raindancers/raindancers-crew.ICrewBackupBucket.property.bucket"></a>
1752
+
1753
+ ```typescript
1754
+ public readonly bucket: IBucket;
1755
+ ```
1756
+
1757
+ - *Type:* aws-cdk-lib.aws_s3.IBucket
1758
+
1759
+ The destination bucket name.
1760
+
1761
+ ---
1762
+
1763
+ ## Enums <a name="Enums" id="Enums"></a>
1764
+
1765
+ ### CrewArchitecture <a name="CrewArchitecture" id="@raindancers/raindancers-crew.CrewArchitecture"></a>
1766
+
1767
+ CPU architecture for the KiroCrew EC2 instance.
1768
+
1769
+ Selects the matching
1770
+ Amazon Linux 2023 AMI and the pinned Node.js / kiro-cli download.
1771
+
1772
+ #### Members <a name="Members" id="Members"></a>
1773
+
1774
+ | **Name** | **Description** |
1775
+ | --- | --- |
1776
+ | <code><a href="#@raindancers/raindancers-crew.CrewArchitecture.ARM64">ARM64</a></code> | 64-bit ARM (Graviton). |
1777
+ | <code><a href="#@raindancers/raindancers-crew.CrewArchitecture.X86_64">X86_64</a></code> | 64-bit x86. |
1778
+
1779
+ ---
1780
+
1781
+ ##### `ARM64` <a name="ARM64" id="@raindancers/raindancers-crew.CrewArchitecture.ARM64"></a>
1782
+
1783
+ 64-bit ARM (Graviton).
1784
+
1785
+ The upstream default.
1786
+
1787
+ ---
1788
+
1789
+
1790
+ ##### `X86_64` <a name="X86_64" id="@raindancers/raindancers-crew.CrewArchitecture.X86_64"></a>
1791
+
1792
+ 64-bit x86.
1793
+
1794
+ ---
1795
+
1796
+
1797
+ ### FargateCpuArchitecture <a name="FargateCpuArchitecture" id="@raindancers/raindancers-crew.FargateCpuArchitecture"></a>
1798
+
1799
+ CPU architecture a crew container image was built for.
1800
+
1801
+ Must match the image:
1802
+ a task whose runtime platform disagrees with its image fails at start.
1803
+
1804
+ #### Members <a name="Members" id="Members"></a>
1805
+
1806
+ | **Name** | **Description** |
1807
+ | --- | --- |
1808
+ | <code><a href="#@raindancers/raindancers-crew.FargateCpuArchitecture.X86_64">X86_64</a></code> | *No description.* |
1809
+ | <code><a href="#@raindancers/raindancers-crew.FargateCpuArchitecture.ARM64">ARM64</a></code> | *No description.* |
1810
+
1811
+ ---
1812
+
1813
+ ##### `X86_64` <a name="X86_64" id="@raindancers/raindancers-crew.FargateCpuArchitecture.X86_64"></a>
1814
+
1815
+ ---
1816
+
1817
+
1818
+ ##### `ARM64` <a name="ARM64" id="@raindancers/raindancers-crew.FargateCpuArchitecture.ARM64"></a>
1819
+
1820
+ ---
1821
+