@prism-d1/cli 1.0.79 → 1.0.80
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/dist/assets/github-workflows/prism-ai-metrics.yml +83 -122
- package/dist/assets/github-workflows/prism-eval-gate-kiro.yml +66 -0
- package/dist/assets/github-workflows/prism-eval-gate.yml +1 -1
- package/dist/assets/gitlab-workflows/.gitlab-ci.yml +0 -3
- package/dist/assets/gitlab-workflows/prism-ai-metrics.yml +53 -56
- package/dist/assets/infra/bin/app.ts +1 -0
- package/dist/assets/infra/lib/constructs/otel-collector-construct.ts +4 -0
- package/dist/assets/infra/lib/dashboard-stack.ts +378 -1235
- package/dist/assets/infra/lib/lambda/event-schema.ts +144 -0
- package/dist/assets/infra/lib/lambda/metrics-processor.ts +124 -36
- package/dist/assets/infra/lib/lambda/otel-receiver.ts +249 -35
- package/dist/assets/infra/lib/lambda/security-remediation-tracker.ts +17 -2
- package/dist/assets/infra/lib/lambda/velocity-widget.ts +1483 -0
- package/dist/assets/infra/lib/metrics-pipeline-stack.ts +110 -119
- package/dist/assets/infra/package.json +2 -1
- package/dist/assets/infra/tsconfig.json +9 -2
- package/dist/src/commands/bootstrapper/install-eval-harness.d.ts +8 -2
- package/dist/src/commands/bootstrapper/install-eval-harness.d.ts.map +1 -1
- package/dist/src/commands/bootstrapper/install-eval-harness.js +32 -32
- package/dist/src/commands/bootstrapper/install-eval-harness.js.map +1 -1
- package/dist/src/commands/bootstrapper/install-github-workflows.d.ts.map +1 -1
- package/dist/src/commands/bootstrapper/install-github-workflows.js +7 -2
- package/dist/src/commands/bootstrapper/install-github-workflows.js.map +1 -1
- package/dist/src/commands/bootstrapper/install-gitlab-workflows.d.ts.map +1 -1
- package/dist/src/commands/bootstrapper/install-gitlab-workflows.js +7 -1
- package/dist/src/commands/bootstrapper/install-gitlab-workflows.js.map +1 -1
- package/dist/src/utils/region.d.ts +50 -0
- package/dist/src/utils/region.d.ts.map +1 -0
- package/dist/src/utils/region.js +62 -0
- package/dist/src/utils/region.js.map +1 -0
- package/package.json +2 -2
- package/dist/assets/eval-harness/README.md +0 -144
- package/dist/assets/github-workflows/README.md +0 -110
- package/dist/assets/github-workflows/prism-dora-weekly.yml +0 -334
- package/dist/assets/gitlab-workflows/prism-dora-weekly.yml +0 -181
- package/dist/assets/infra/lib/lambda/defect-correlator.ts +0 -142
- package/dist/assets/infra/lib/lambda/spec-to-code-calculator.ts +0 -123
- package/dist/assets/metric-hooks/README.md +0 -107
|
@@ -27,6 +27,8 @@ export class MetricsPipelineStack extends cdk.Stack {
|
|
|
27
27
|
public readonly guardrail: BedrockGuardrailConstruct;
|
|
28
28
|
public readonly securityAgent?: SecurityAgentConstruct;
|
|
29
29
|
public readonly otelCollector?: OtelCollectorConstruct;
|
|
30
|
+
/** ARN of the Team Velocity custom-widget Lambda (DDB-backed panels). */
|
|
31
|
+
public velocityWidgetArn!: string;
|
|
30
32
|
|
|
31
33
|
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
|
|
32
34
|
super(scope, id, props);
|
|
@@ -247,6 +249,15 @@ export class MetricsPipelineStack extends cdk.Stack {
|
|
|
247
249
|
description: 'Processes PRISM D1 metric events from EventBridge into DynamoDB and CloudWatch',
|
|
248
250
|
});
|
|
249
251
|
|
|
252
|
+
// Cap Lambda's own async retry of function errors (default 2, up to 6h).
|
|
253
|
+
// EventBridge target retries are bounded separately below; together these
|
|
254
|
+
// prevent the unbounded retry amplification behind the July 2026 storm.
|
|
255
|
+
new lambda.EventInvokeConfig(this, 'MetricsProcessorInvokeConfig', {
|
|
256
|
+
function: metricsProcessor,
|
|
257
|
+
retryAttempts: 1,
|
|
258
|
+
maxEventAge: cdk.Duration.hours(1),
|
|
259
|
+
});
|
|
260
|
+
|
|
250
261
|
// -------------------------------------------------------
|
|
251
262
|
// IAM permissions for the processor
|
|
252
263
|
// -------------------------------------------------------
|
|
@@ -288,6 +299,26 @@ export class MetricsPipelineStack extends cdk.Stack {
|
|
|
288
299
|
'prism.d1.quality',
|
|
289
300
|
];
|
|
290
301
|
|
|
302
|
+
// DLQ for events the processor fails to handle. Combined with
|
|
303
|
+
// retryAttempts: 1 this caps the blast radius of a poison event or a
|
|
304
|
+
// downstream outage — the July 2026 retry storm (~108M invocations/day,
|
|
305
|
+
// 445 GB of logs) was driven by unbounded async retries against a
|
|
306
|
+
// throttling failure. Events land here for inspection instead of looping.
|
|
307
|
+
const processorDlq = new sqs.Queue(this, 'MetricsProcessorDlq', {
|
|
308
|
+
queueName: 'prism-d1-metrics-processor-dlq',
|
|
309
|
+
encryption: sqs.QueueEncryption.KMS,
|
|
310
|
+
encryptionMasterKey: prismKmsKey,
|
|
311
|
+
retentionPeriod: cdk.Duration.days(14),
|
|
312
|
+
enforceSSL: true,
|
|
313
|
+
});
|
|
314
|
+
// EventBridge needs KMS grants to write to the CMK-encrypted DLQ —
|
|
315
|
+
// without them messages are dropped silently (no error, no metric).
|
|
316
|
+
prismKmsKey.grant(
|
|
317
|
+
new iam.ServicePrincipal('events.amazonaws.com'),
|
|
318
|
+
'kms:GenerateDataKey',
|
|
319
|
+
'kms:Decrypt',
|
|
320
|
+
);
|
|
321
|
+
|
|
291
322
|
for (const detailType of detailTypes) {
|
|
292
323
|
const ruleName = detailType.replace(/\./g, '-');
|
|
293
324
|
new events.Rule(this, `Rule-${ruleName}`, {
|
|
@@ -297,7 +328,13 @@ export class MetricsPipelineStack extends cdk.Stack {
|
|
|
297
328
|
source: ['prism.d1.velocity'],
|
|
298
329
|
detailType: [detailType],
|
|
299
330
|
},
|
|
300
|
-
targets: [
|
|
331
|
+
targets: [
|
|
332
|
+
new targets.LambdaFunction(metricsProcessor, {
|
|
333
|
+
deadLetterQueue: processorDlq,
|
|
334
|
+
retryAttempts: 1,
|
|
335
|
+
maxEventAge: cdk.Duration.hours(1),
|
|
336
|
+
}),
|
|
337
|
+
],
|
|
301
338
|
description: `Routes ${detailType} events to the metrics processor`,
|
|
302
339
|
});
|
|
303
340
|
}
|
|
@@ -494,6 +531,63 @@ export class MetricsPipelineStack extends cdk.Stack {
|
|
|
494
531
|
);
|
|
495
532
|
}
|
|
496
533
|
|
|
534
|
+
// -------------------------------------------------------
|
|
535
|
+
// Velocity custom-widget Lambda — DDB-backed panels for the
|
|
536
|
+
// Team Velocity dashboard. Reads the events table via the
|
|
537
|
+
// by-detail-type GSI (full history, no metric-dimension matching).
|
|
538
|
+
// Invoked by CloudWatch dashboards with the viewing user's IAM creds.
|
|
539
|
+
// -------------------------------------------------------
|
|
540
|
+
const velocityWidget = new lambda.Function(this, 'VelocityWidget', {
|
|
541
|
+
functionName: 'prism-d1-velocity-widget',
|
|
542
|
+
runtime: lambda.Runtime.NODEJS_22_X,
|
|
543
|
+
handler: 'velocity-widget.handler',
|
|
544
|
+
code: lambda.Code.fromAsset(path.join(__dirname, 'lambda'), {
|
|
545
|
+
bundling: {
|
|
546
|
+
image: lambda.Runtime.NODEJS_22_X.bundlingImage,
|
|
547
|
+
command: [
|
|
548
|
+
'bash', '-c',
|
|
549
|
+
[
|
|
550
|
+
'npm init -y > /dev/null 2>&1',
|
|
551
|
+
'npm install --save @aws-sdk/client-dynamodb @aws-sdk/client-lambda esbuild > /dev/null 2>&1',
|
|
552
|
+
'npx esbuild velocity-widget.ts --bundle --platform=node --target=node22 --outfile=/asset-output/velocity-widget.js --external:@aws-sdk/*',
|
|
553
|
+
].join(' && '),
|
|
554
|
+
],
|
|
555
|
+
local: {
|
|
556
|
+
tryBundle(outputDir: string): boolean {
|
|
557
|
+
try {
|
|
558
|
+
require('child_process').execSync(
|
|
559
|
+
`npx esbuild ${path.join(__dirname, 'lambda', 'velocity-widget.ts')} --bundle --platform=node --target=node22 --outfile=${path.join(outputDir, 'velocity-widget.js')} --external:@aws-sdk/*`,
|
|
560
|
+
{ stdio: 'pipe' },
|
|
561
|
+
);
|
|
562
|
+
return true;
|
|
563
|
+
} catch { return false; }
|
|
564
|
+
},
|
|
565
|
+
},
|
|
566
|
+
},
|
|
567
|
+
}),
|
|
568
|
+
timeout: cdk.Duration.seconds(30),
|
|
569
|
+
memorySize: 256,
|
|
570
|
+
environment: {
|
|
571
|
+
EVENTS_TABLE: this.eventsTable.tableName,
|
|
572
|
+
RECEIVER_FUNCTION: 'prism-d1-otel-receiver',
|
|
573
|
+
},
|
|
574
|
+
logRetention: logs.RetentionDays.ONE_MONTH,
|
|
575
|
+
description: 'CloudWatch custom widget: Team Velocity panels from the PRISM events table',
|
|
576
|
+
});
|
|
577
|
+
this.eventsTable.grantReadData(velocityWidget);
|
|
578
|
+
if (this.otelCollector) {
|
|
579
|
+
// aidora view delegates attribution KPIs to the receiver; without the
|
|
580
|
+
// collector the view degrades gracefully (eval KPI only).
|
|
581
|
+
this.otelCollector.receiverFunction.grantInvoke(velocityWidget);
|
|
582
|
+
}
|
|
583
|
+
this.velocityWidgetArn = velocityWidget.functionArn;
|
|
584
|
+
NagSuppressions.addResourceSuppressions(
|
|
585
|
+
velocityWidget,
|
|
586
|
+
[{ id: 'AwsSolutions-IAM4', reason: 'AWSLambdaBasicExecutionRole for CloudWatch Logs' },
|
|
587
|
+
{ id: 'AwsSolutions-IAM5', reason: 'Table read grant includes index ARNs (table/*/index/*)' }],
|
|
588
|
+
true,
|
|
589
|
+
);
|
|
590
|
+
|
|
497
591
|
// -------------------------------------------------------
|
|
498
592
|
// AWS Security Agent (opt-in — requires Security Agent access)
|
|
499
593
|
// Enable with: npx cdk deploy --context enableSecurityAgent=true
|
|
@@ -686,125 +780,22 @@ export class MetricsPipelineStack extends cdk.Stack {
|
|
|
686
780
|
});
|
|
687
781
|
|
|
688
782
|
// -------------------------------------------------------
|
|
689
|
-
// Defect Correlator
|
|
783
|
+
// REMOVED: Defect Correlator + Spec-to-Code Calculator
|
|
784
|
+
//
|
|
785
|
+
// Both were permanent no-ops. Each keyed off `prism.d1.commit`, which no
|
|
786
|
+
// DEPLOYED producer emits — the only emitters are the demo-data generator
|
|
787
|
+
// and docs/reference/github-webhook-handler/, which CDK never deploys.
|
|
788
|
+
// defect-correlator skipped every event via `detailType !==
|
|
789
|
+
// 'prism.d1.commit'` and returned early; spec-to-code-calculator queried
|
|
790
|
+
// for the same type (with a Limit:1 + FilterExpression bug on top, so the
|
|
791
|
+
// filter never ran) and found nothing. They consumed IAM, VPC attachments,
|
|
792
|
+
// and log groups while implying capability the pipeline did not have.
|
|
793
|
+
//
|
|
794
|
+
// Their metrics (PostMergeDefectRate, SpecToCodeHours) and the
|
|
795
|
+
// prism.d1.quality event type went with them. The working equivalent of
|
|
796
|
+
// post-merge defect rate is RevertedAICommits / MergedAICommits from the
|
|
797
|
+
// attribution store, already on the dashboards.
|
|
690
798
|
// -------------------------------------------------------
|
|
691
|
-
const defectCorrelator = new lambda.Function(this, 'DefectCorrelator', {
|
|
692
|
-
functionName: 'prism-d1-defect-correlator',
|
|
693
|
-
runtime: lambda.Runtime.NODEJS_22_X,
|
|
694
|
-
handler: 'defect-correlator.handler',
|
|
695
|
-
...lambdaVpcProps,
|
|
696
|
-
code: lambda.Code.fromAsset(path.join(__dirname, 'lambda'), {
|
|
697
|
-
bundling: {
|
|
698
|
-
image: lambda.Runtime.NODEJS_22_X.bundlingImage,
|
|
699
|
-
command: [
|
|
700
|
-
'bash', '-c',
|
|
701
|
-
[
|
|
702
|
-
'npm init -y > /dev/null 2>&1',
|
|
703
|
-
'npm install --save @aws-sdk/client-dynamodb @aws-sdk/client-eventbridge esbuild > /dev/null 2>&1',
|
|
704
|
-
'npx esbuild defect-correlator.ts --bundle --platform=node --target=node22 --outfile=/asset-output/defect-correlator.js --external:@aws-sdk/*',
|
|
705
|
-
].join(' && '),
|
|
706
|
-
],
|
|
707
|
-
local: {
|
|
708
|
-
tryBundle(outputDir: string): boolean {
|
|
709
|
-
try {
|
|
710
|
-
const { execSync } = require('child_process');
|
|
711
|
-
execSync(
|
|
712
|
-
`npx esbuild ${path.join(__dirname, 'lambda', 'defect-correlator.ts')} --bundle --platform=node --target=node22 --outfile=${path.join(outputDir, 'defect-correlator.js')} --external:@aws-sdk/*`,
|
|
713
|
-
{ stdio: 'pipe' },
|
|
714
|
-
);
|
|
715
|
-
return true;
|
|
716
|
-
} catch {
|
|
717
|
-
return false;
|
|
718
|
-
}
|
|
719
|
-
},
|
|
720
|
-
},
|
|
721
|
-
},
|
|
722
|
-
}),
|
|
723
|
-
timeout: cdk.Duration.seconds(30),
|
|
724
|
-
memorySize: 256,
|
|
725
|
-
environment: {
|
|
726
|
-
EVENTS_TABLE: this.eventsTable.tableName,
|
|
727
|
-
EVENT_BUS_NAME: this.eventBus.eventBusName,
|
|
728
|
-
LOOKBACK_HOURS: '24',
|
|
729
|
-
},
|
|
730
|
-
logRetention: logs.RetentionDays.ONE_MONTH,
|
|
731
|
-
description: 'Correlates deployment failures with AI vs human commit origins',
|
|
732
|
-
});
|
|
733
|
-
|
|
734
|
-
this.eventsTable.grantReadData(defectCorrelator);
|
|
735
|
-
this.eventBus.grantPutEventsTo(defectCorrelator);
|
|
736
|
-
|
|
737
|
-
// Trigger defect correlator on failed deploy events
|
|
738
|
-
new events.Rule(this, 'DeployToDefectCorrelatorRule', {
|
|
739
|
-
ruleName: 'prism-d1-deploy-to-defect-correlator',
|
|
740
|
-
eventBus: this.eventBus,
|
|
741
|
-
eventPattern: {
|
|
742
|
-
source: ['prism.d1.velocity'],
|
|
743
|
-
detailType: ['prism.d1.deploy'],
|
|
744
|
-
},
|
|
745
|
-
targets: [new targets.LambdaFunction(defectCorrelator)],
|
|
746
|
-
description: 'Triggers defect correlation on deployment events',
|
|
747
|
-
});
|
|
748
|
-
|
|
749
|
-
// -------------------------------------------------------
|
|
750
|
-
// Spec-to-Code Calculator (Pillar 7)
|
|
751
|
-
// -------------------------------------------------------
|
|
752
|
-
const specToCodeCalc = new lambda.Function(this, 'SpecToCodeCalculator', {
|
|
753
|
-
functionName: 'prism-d1-spec-to-code-calculator',
|
|
754
|
-
runtime: lambda.Runtime.NODEJS_22_X,
|
|
755
|
-
handler: 'spec-to-code-calculator.handler',
|
|
756
|
-
...lambdaVpcProps,
|
|
757
|
-
code: lambda.Code.fromAsset(path.join(__dirname, 'lambda'), {
|
|
758
|
-
bundling: {
|
|
759
|
-
image: lambda.Runtime.NODEJS_22_X.bundlingImage,
|
|
760
|
-
command: [
|
|
761
|
-
'bash', '-c',
|
|
762
|
-
[
|
|
763
|
-
'npm init -y > /dev/null 2>&1',
|
|
764
|
-
'npm install --save @aws-sdk/client-dynamodb @aws-sdk/client-eventbridge esbuild > /dev/null 2>&1',
|
|
765
|
-
'npx esbuild spec-to-code-calculator.ts --bundle --platform=node --target=node22 --outfile=/asset-output/spec-to-code-calculator.js --external:@aws-sdk/*',
|
|
766
|
-
].join(' && '),
|
|
767
|
-
],
|
|
768
|
-
local: {
|
|
769
|
-
tryBundle(outputDir: string): boolean {
|
|
770
|
-
try {
|
|
771
|
-
const { execSync } = require('child_process');
|
|
772
|
-
execSync(
|
|
773
|
-
`npx esbuild ${path.join(__dirname, 'lambda', 'spec-to-code-calculator.ts')} --bundle --platform=node --target=node22 --outfile=${path.join(outputDir, 'spec-to-code-calculator.js')} --external:@aws-sdk/*`,
|
|
774
|
-
{ stdio: 'pipe' },
|
|
775
|
-
);
|
|
776
|
-
return true;
|
|
777
|
-
} catch {
|
|
778
|
-
return false;
|
|
779
|
-
}
|
|
780
|
-
},
|
|
781
|
-
},
|
|
782
|
-
},
|
|
783
|
-
}),
|
|
784
|
-
timeout: cdk.Duration.seconds(30),
|
|
785
|
-
memorySize: 256,
|
|
786
|
-
environment: {
|
|
787
|
-
EVENTS_TABLE: this.eventsTable.tableName,
|
|
788
|
-
EVENT_BUS_NAME: this.eventBus.eventBusName,
|
|
789
|
-
},
|
|
790
|
-
logRetention: logs.RetentionDays.ONE_MONTH,
|
|
791
|
-
description: 'Calculates spec-to-code hours for merged PRs with spec references',
|
|
792
|
-
});
|
|
793
|
-
|
|
794
|
-
this.eventsTable.grantReadData(specToCodeCalc);
|
|
795
|
-
this.eventBus.grantPutEventsTo(specToCodeCalc);
|
|
796
|
-
|
|
797
|
-
// Trigger spec-to-code calculator on merged PR events
|
|
798
|
-
new events.Rule(this, 'PrToSpecCalcRule', {
|
|
799
|
-
ruleName: 'prism-d1-pr-to-spec-calc',
|
|
800
|
-
eventBus: this.eventBus,
|
|
801
|
-
eventPattern: {
|
|
802
|
-
source: ['prism.d1.velocity'],
|
|
803
|
-
detailType: ['prism.d1.pr'],
|
|
804
|
-
},
|
|
805
|
-
targets: [new targets.LambdaFunction(specToCodeCalc)],
|
|
806
|
-
description: 'Triggers spec-to-code calculation on merged PR events',
|
|
807
|
-
});
|
|
808
799
|
|
|
809
800
|
// -------------------------------------------------------
|
|
810
801
|
// AWS Security Agent Integration
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
"compilerOptions": {
|
|
3
3
|
"target": "ES2022",
|
|
4
4
|
"module": "commonjs",
|
|
5
|
-
"lib": [
|
|
5
|
+
"lib": [
|
|
6
|
+
"es2022"
|
|
7
|
+
],
|
|
6
8
|
"declaration": true,
|
|
7
9
|
"strict": true,
|
|
8
10
|
"noImplicitAny": true,
|
|
@@ -20,5 +22,10 @@
|
|
|
20
22
|
"outDir": "./dist",
|
|
21
23
|
"rootDir": "."
|
|
22
24
|
},
|
|
23
|
-
"exclude": [
|
|
25
|
+
"exclude": [
|
|
26
|
+
"node_modules",
|
|
27
|
+
"dist",
|
|
28
|
+
"lib/lambda",
|
|
29
|
+
"scripts"
|
|
30
|
+
]
|
|
24
31
|
}
|
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
declare const _default: {
|
|
2
2
|
description: string;
|
|
3
|
-
options: {
|
|
3
|
+
options: ({
|
|
4
4
|
flags: string;
|
|
5
5
|
description: string;
|
|
6
|
-
|
|
6
|
+
default?: undefined;
|
|
7
|
+
} | {
|
|
8
|
+
flags: string;
|
|
9
|
+
description: string;
|
|
10
|
+
default: string;
|
|
11
|
+
})[];
|
|
7
12
|
action(opts: {
|
|
8
13
|
mode?: string;
|
|
9
14
|
withRubrics?: boolean;
|
|
10
15
|
model?: string;
|
|
11
16
|
threshold?: string;
|
|
17
|
+
region?: string;
|
|
12
18
|
uninstall?: boolean;
|
|
13
19
|
}): Promise<void>;
|
|
14
20
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-eval-harness.d.ts","sourceRoot":"","sources":["../../../../src/commands/bootstrapper/install-eval-harness.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"install-eval-harness.d.ts","sourceRoot":"","sources":["../../../../src/commands/bootstrapper/install-eval-harness.ts"],"names":[],"mappings":";;;;;;;;;;;iBA2DqB;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE;;AAVvI,wBAoCE"}
|
|
@@ -1,9 +1,35 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, writeFileSync, copyFileSync, chmodSync, readdirSync } from 'node:fs';
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync, chmodSync, readdirSync } from 'node:fs';
|
|
2
2
|
import { resolve, dirname } from 'node:path';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
4
|
import { execSync } from 'node:child_process';
|
|
5
5
|
import { createInterface } from 'node:readline';
|
|
6
6
|
import { getAssetPath } from '../../utils/root.js';
|
|
7
|
+
import { applyRegion, findDefaultRegionRefs, DEFAULT_REGION } from '../../utils/region.js';
|
|
8
|
+
/**
|
|
9
|
+
* Copies a workflow asset into the repo with the region templated.
|
|
10
|
+
*
|
|
11
|
+
* Must not be a bare copyFileSync: these assets are authored against
|
|
12
|
+
* DEFAULT_REGION, and an unsubstituted copy sends the Continuum scan and
|
|
13
|
+
* event-emission calls to a region where the agent space and scan bucket do
|
|
14
|
+
* not exist -- which fails the gate closed and blocks merges.
|
|
15
|
+
*/
|
|
16
|
+
async function writeWorkflow(src, dest, region, label, ask) {
|
|
17
|
+
if (existsSync(dest)) {
|
|
18
|
+
const overwrite = await ask('Workflow already exists. Overwrite? [y/N]', 'n');
|
|
19
|
+
if (overwrite.toLowerCase() !== 'y') {
|
|
20
|
+
console.log(' Skipped workflow.');
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const content = applyRegion(readFileSync(src, 'utf-8'), region);
|
|
25
|
+
const stragglers = findDefaultRegionRefs(content, label);
|
|
26
|
+
if (stragglers.length > 0) {
|
|
27
|
+
console.warn(` ⚠ ${stragglers.length} unconverted region reference(s):`);
|
|
28
|
+
stragglers.forEach(s => console.warn(` ${s}`));
|
|
29
|
+
}
|
|
30
|
+
writeFileSync(dest, content);
|
|
31
|
+
console.log(`✓ Installed ${label} (region: ${region})`);
|
|
32
|
+
}
|
|
7
33
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
34
|
const EVAL_SOURCE = getAssetPath(import.meta.url, 'bootstrapper/eval-harness');
|
|
9
35
|
function prompt(question, defaultValue) {
|
|
@@ -18,6 +44,7 @@ export default {
|
|
|
18
44
|
{ flags: '--with-rubrics', description: 'Include production rubrics (bedrock mode only)' },
|
|
19
45
|
{ flags: '--model <id>', description: 'Bedrock model ID for evaluation (bedrock mode only)' },
|
|
20
46
|
{ flags: '--threshold <n>', description: 'Pass threshold (0-1)' },
|
|
47
|
+
{ flags: '--region <region>', description: 'AWS region for EventBridge/CloudWatch/Continuum', default: DEFAULT_REGION },
|
|
21
48
|
{ flags: '--uninstall', description: 'Remove eval-harness directory and steering files' },
|
|
22
49
|
],
|
|
23
50
|
async action(opts) {
|
|
@@ -46,6 +73,7 @@ export default {
|
|
|
46
73
|
},
|
|
47
74
|
};
|
|
48
75
|
async function installKiroMode(gitRoot, opts) {
|
|
76
|
+
const region = opts.region || DEFAULT_REGION;
|
|
49
77
|
// --- Install steering file ---
|
|
50
78
|
const steeringDir = resolve(gitRoot, '.kiro/steering');
|
|
51
79
|
mkdirSync(steeringDir, { recursive: true });
|
|
@@ -70,21 +98,7 @@ async function installKiroMode(gitRoot, opts) {
|
|
|
70
98
|
const workflowSrc = getAssetPath(import.meta.url, 'bootstrapper/github-workflows/prism-eval-gate-kiro.yml');
|
|
71
99
|
if (existsSync(workflowSrc)) {
|
|
72
100
|
mkdirSync(workflowsDir, { recursive: true });
|
|
73
|
-
|
|
74
|
-
if (existsSync(dest)) {
|
|
75
|
-
const overwrite = await prompt('Workflow already exists. Overwrite? [y/N]', 'n');
|
|
76
|
-
if (overwrite.toLowerCase() !== 'y') {
|
|
77
|
-
console.log(' Skipped workflow.');
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
copyFileSync(workflowSrc, dest);
|
|
81
|
-
console.log('✓ Updated .github/workflows/prism-eval-gate.yml');
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
copyFileSync(workflowSrc, dest);
|
|
86
|
-
console.log('✓ Installed .github/workflows/prism-eval-gate.yml');
|
|
87
|
-
}
|
|
101
|
+
await writeWorkflow(workflowSrc, resolve(workflowsDir, 'prism-eval-gate.yml'), region, '.github/workflows/prism-eval-gate.yml', prompt);
|
|
88
102
|
}
|
|
89
103
|
console.log('\n════════════════════════════════════════════════');
|
|
90
104
|
console.log(' ✅ Kiro eval gate installed!');
|
|
@@ -101,7 +115,7 @@ async function installBedrockMode(gitRoot, targetDir, opts) {
|
|
|
101
115
|
// --- Config ---
|
|
102
116
|
const model = opts.model || await prompt('Eval model ID', 'us.anthropic.claude-haiku-4-5-20251001-v1:0');
|
|
103
117
|
const threshold = opts.threshold || await prompt('Pass threshold', '0.82');
|
|
104
|
-
const region = await prompt('AWS region',
|
|
118
|
+
const region = opts.region || await prompt('AWS region', DEFAULT_REGION);
|
|
105
119
|
// --- Install script + config ---
|
|
106
120
|
mkdirSync(resolve(targetDir, 'rubrics'), { recursive: true });
|
|
107
121
|
// Copy run-eval.sh
|
|
@@ -134,21 +148,7 @@ async function installBedrockMode(gitRoot, targetDir, opts) {
|
|
|
134
148
|
const workflowSrc = getAssetPath(import.meta.url, 'bootstrapper/github-workflows/prism-eval-gate.yml');
|
|
135
149
|
if (existsSync(workflowSrc)) {
|
|
136
150
|
mkdirSync(workflowsDir, { recursive: true });
|
|
137
|
-
|
|
138
|
-
if (existsSync(dest)) {
|
|
139
|
-
const overwrite = await prompt('Workflow already exists. Overwrite? [y/N]', 'n');
|
|
140
|
-
if (overwrite.toLowerCase() !== 'y') {
|
|
141
|
-
console.log(' Skipped workflow.');
|
|
142
|
-
}
|
|
143
|
-
else {
|
|
144
|
-
copyFileSync(workflowSrc, dest);
|
|
145
|
-
console.log('✓ Updated .github/workflows/prism-eval-gate.yml');
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
else {
|
|
149
|
-
copyFileSync(workflowSrc, dest);
|
|
150
|
-
console.log('✓ Installed .github/workflows/prism-eval-gate.yml');
|
|
151
|
-
}
|
|
151
|
+
await writeWorkflow(workflowSrc, resolve(workflowsDir, 'prism-eval-gate.yml'), region, '.github/workflows/prism-eval-gate.yml', prompt);
|
|
152
152
|
}
|
|
153
153
|
console.log('\n════════════════════════════════════════════════');
|
|
154
154
|
console.log(' ✅ Eval harness installed (legacy Bedrock mode)!');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-eval-harness.js","sourceRoot":"","sources":["../../../../src/commands/bootstrapper/install-eval-harness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"install-eval-harness.js","sourceRoot":"","sources":["../../../../src/commands/bootstrapper/install-eval-harness.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-github-workflows.d.ts","sourceRoot":"","sources":["../../../../src/commands/bootstrapper/install-github-workflows.ts"],"names":[],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"install-github-workflows.d.ts","sourceRoot":"","sources":["../../../../src/commands/bootstrapper/install-github-workflows.ts"],"names":[],"mappings":";;;;;;;iBAWqB;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;;AAN3D,wBAsCE"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { mkdirSync, readFileSync, writeFileSync, readdirSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { getAssetPath } from '../../utils/root.js';
|
|
4
|
+
import { applyRegion, findDefaultRegionRefs } from '../../utils/region.js';
|
|
4
5
|
export default {
|
|
5
6
|
description: 'Install GitHub Actions workflow templates into the current repo',
|
|
6
7
|
options: [
|
|
@@ -18,8 +19,12 @@ export default {
|
|
|
18
19
|
const files = readdirSync(assetDir).filter(f => f.endsWith('.yml'));
|
|
19
20
|
for (const file of files) {
|
|
20
21
|
let content = readFileSync(join(assetDir, file), 'utf-8');
|
|
21
|
-
content = content
|
|
22
|
-
|
|
22
|
+
content = applyRegion(content, region);
|
|
23
|
+
const stragglers = findDefaultRegionRefs(content, file);
|
|
24
|
+
if (stragglers.length > 0) {
|
|
25
|
+
console.warn(` ⚠ ${file}: ${stragglers.length} unconverted region reference(s):`);
|
|
26
|
+
stragglers.forEach(s => console.warn(` ${s}`));
|
|
27
|
+
}
|
|
23
28
|
writeFileSync(join(outputDir, file), content);
|
|
24
29
|
console.log(` ✓ ${file}`);
|
|
25
30
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-github-workflows.js","sourceRoot":"","sources":["../../../../src/commands/bootstrapper/install-github-workflows.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC9E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"install-github-workflows.js","sourceRoot":"","sources":["../../../../src/commands/bootstrapper/install-github-workflows.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC9E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE3E,eAAe;IACb,WAAW,EAAE,iEAAiE;IAC9E,OAAO,EAAE;QACP,EAAE,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,uCAAuC,EAAE,OAAO,EAAE,WAAW,EAAE;QAC1G,EAAE,KAAK,EAAE,oBAAoB,EAAE,WAAW,EAAE,kBAAkB,EAAE,OAAO,EAAE,mBAAmB,EAAE;KAC/F;IACD,KAAK,CAAC,MAAM,CAAC,IAA4C;QACvD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,WAAW,CAAC;QAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAEjC,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,EAAE,CAAC,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,cAAc,SAAS,KAAK,CAAC,CAAC;QAE1C,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE1C,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,uCAAuC,CAAC,CAAC,OAAO,CAAC,uBAAuB,EAAE,EAAE,CAAC,CAAC;QAC7H,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QAEpE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;YAC1D,OAAO,GAAG,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YACvC,MAAM,UAAU,GAAG,qBAAqB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YACxD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC1B,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,KAAK,UAAU,CAAC,MAAM,mCAAmC,CAAC,CAAC;gBACnF,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;YACtD,CAAC;YACD,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;YAC9C,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;QAC7B,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,iBAAiB,KAAK,CAAC,MAAM,sBAAsB,SAAS,GAAG,CAAC,CAAC;QAC7E,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;QAClE,OAAO,CAAC,GAAG,CAAC,6DAA6D,CAAC,CAAC;QAC3E,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC;CACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-gitlab-workflows.d.ts","sourceRoot":"","sources":["../../../../src/commands/bootstrapper/install-gitlab-workflows.ts"],"names":[],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"install-gitlab-workflows.d.ts","sourceRoot":"","sources":["../../../../src/commands/bootstrapper/install-gitlab-workflows.ts"],"names":[],"mappings":";;;;;;;iBAwBqB;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;;AAP/E,wBAoDE"}
|
|
@@ -2,6 +2,7 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync, readdirSync } from
|
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { createInterface } from 'node:readline';
|
|
4
4
|
import { getAssetPath } from '../../utils/root.js';
|
|
5
|
+
import { applyRegion, findDefaultRegionRefs } from '../../utils/region.js';
|
|
5
6
|
function prompt(question, defaultValue) {
|
|
6
7
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
7
8
|
const suffix = defaultValue ? ` [${defaultValue}]` : '';
|
|
@@ -34,7 +35,12 @@ export default {
|
|
|
34
35
|
let content = readFileSync(join(assetDir, file), 'utf-8');
|
|
35
36
|
// Template the audience and region
|
|
36
37
|
content = content.replace(/aud: https:\/\/gitlab\.com/g, `aud: ${gitlabUrl}`);
|
|
37
|
-
content = content
|
|
38
|
+
content = applyRegion(content, region);
|
|
39
|
+
const stragglers = findDefaultRegionRefs(content, file);
|
|
40
|
+
if (stragglers.length > 0) {
|
|
41
|
+
console.warn(` ⚠ ${file}: ${stragglers.length} unconverted region reference(s):`);
|
|
42
|
+
stragglers.forEach(s => console.warn(` ${s}`));
|
|
43
|
+
}
|
|
38
44
|
writeFileSync(join(outputDir, file), content);
|
|
39
45
|
console.log(` ✓ ${file}`);
|
|
40
46
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-gitlab-workflows.js","sourceRoot":"","sources":["../../../../src/commands/bootstrapper/install-gitlab-workflows.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC1F,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"install-gitlab-workflows.js","sourceRoot":"","sources":["../../../../src/commands/bootstrapper/install-gitlab-workflows.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Region templating for bootstrapper assets.
|
|
3
|
+
*
|
|
4
|
+
* The shipped workflow assets are authored against DEFAULT_REGION. Every
|
|
5
|
+
* installer that copies one into a user's repo must run the content through
|
|
6
|
+
* applyRegion() so the whole file targets a single region.
|
|
7
|
+
*
|
|
8
|
+
* Why a bare-token replace rather than per-syntax rules:
|
|
9
|
+
*
|
|
10
|
+
* The workflows spell the region three different ways -- `aws-region:` (the
|
|
11
|
+
* configure-aws-credentials input), `--region` (an AWS CLI flag), and
|
|
12
|
+
* `AWS_REGION:` / `AWS_DEFAULT_REGION:` (step-level env vars). The installers
|
|
13
|
+
* previously matched a subset each: install-github-workflows handled
|
|
14
|
+
* `aws-region:` and `--region` but not the env form, install-gitlab-workflows
|
|
15
|
+
* handled only the env form, and install-eval-harness did a raw copyFileSync
|
|
16
|
+
* with no substitution at all.
|
|
17
|
+
*
|
|
18
|
+
* A partial rewrite is worse than none. It vends OIDC credentials for the
|
|
19
|
+
* requested region while leaving the AWS Continuum scan and event-emission
|
|
20
|
+
* calls pointed at DEFAULT_REGION, so those calls run against a region where
|
|
21
|
+
* the agent space, scan bucket, and SSM parameters were never created. The
|
|
22
|
+
* eval gate then fails closed and the merge blocks -- a symptom several steps
|
|
23
|
+
* removed from a region string the installer claimed to template.
|
|
24
|
+
*
|
|
25
|
+
* Matching the bare token means a fourth spelling cannot silently escape.
|
|
26
|
+
* This is safe here because no asset embeds the region inside an ARN, Bedrock
|
|
27
|
+
* model id, or endpoint hostname -- verified by assertNoDefaultRegion() in the
|
|
28
|
+
* test suite. If that ever changes, this function needs an exclusion list
|
|
29
|
+
* rather than a looser regex.
|
|
30
|
+
*
|
|
31
|
+
* Keeping every call in one region also satisfies the regional isolation
|
|
32
|
+
* requirement that credentials and the resources they touch stay within a
|
|
33
|
+
* single region boundary (SAX-03 Outcome 3), whose named pitfall is exactly
|
|
34
|
+
* a credential in one region reaching a resource in another.
|
|
35
|
+
*/
|
|
36
|
+
/** The region the bootstrapper assets are authored against. */
|
|
37
|
+
export declare const DEFAULT_REGION = "us-west-2";
|
|
38
|
+
/**
|
|
39
|
+
* Rewrites every occurrence of the authored region to `region`.
|
|
40
|
+
*
|
|
41
|
+
* Word-boundary anchored so a longer region name that merely contains the
|
|
42
|
+
* token cannot be partially rewritten.
|
|
43
|
+
*/
|
|
44
|
+
export declare function applyRegion(content: string, region: string): string;
|
|
45
|
+
/**
|
|
46
|
+
* Returns the `file:line` of every surviving reference to the authored region.
|
|
47
|
+
* Used by installers to warn, and by tests to assert a clean rewrite.
|
|
48
|
+
*/
|
|
49
|
+
export declare function findDefaultRegionRefs(content: string, label?: string): string[];
|
|
50
|
+
//# sourceMappingURL=region.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"region.d.ts","sourceRoot":"","sources":["../../../src/utils/region.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,+DAA+D;AAC/D,eAAO,MAAM,cAAc,cAAc,CAAC;AAE1C;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAGnE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,MAAM,EAAE,CAQ3E"}
|