@prism-d1/cli 1.0.81 → 1.0.83

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/assets/github-workflows/prism-ai-metrics.yml +14 -2
  2. package/dist/assets/github-workflows/prism-eval-gate-kiro.yml +45 -19
  3. package/dist/assets/github-workflows/prism-eval-gate.yml +28 -16
  4. package/dist/assets/gitlab-workflows/prism-ai-metrics.yml +9 -2
  5. package/dist/assets/infra/lib/lambda/security-agent-processor.ts +76 -43
  6. package/dist/assets/infra/lib/metrics-pipeline-stack.ts +8 -0
  7. package/dist/src/commands/bootstrapper/install-eval-harness.d.ts.map +1 -1
  8. package/dist/src/commands/bootstrapper/install-eval-harness.js +9 -0
  9. package/dist/src/commands/bootstrapper/install-eval-harness.js.map +1 -1
  10. package/dist/src/commands/bootstrapper/install-github-workflows.d.ts +1 -0
  11. package/dist/src/commands/bootstrapper/install-github-workflows.d.ts.map +1 -1
  12. package/dist/src/commands/bootstrapper/install-github-workflows.js +69 -9
  13. package/dist/src/commands/bootstrapper/install-github-workflows.js.map +1 -1
  14. package/dist/src/commands/bootstrapper/setup-github-oidc.d.ts +8 -2
  15. package/dist/src/commands/bootstrapper/setup-github-oidc.d.ts.map +1 -1
  16. package/dist/src/commands/bootstrapper/setup-github-oidc.js +17 -2
  17. package/dist/src/commands/bootstrapper/setup-github-oidc.js.map +1 -1
  18. package/dist/src/commands/bootstrapper/setup-gitlab-oidc.d.ts +8 -2
  19. package/dist/src/commands/bootstrapper/setup-gitlab-oidc.d.ts.map +1 -1
  20. package/dist/src/commands/bootstrapper/setup-gitlab-oidc.js +17 -2
  21. package/dist/src/commands/bootstrapper/setup-gitlab-oidc.js.map +1 -1
  22. package/dist/src/commands/workshop/generate-demo-data.d.ts.map +1 -1
  23. package/dist/src/commands/workshop/generate-demo-data.js +124 -12
  24. package/dist/src/commands/workshop/generate-demo-data.js.map +1 -1
  25. package/dist/src/commands/workshop/verify-setup.d.ts.map +1 -1
  26. package/dist/src/commands/workshop/verify-setup.js +0 -2
  27. package/dist/src/commands/workshop/verify-setup.js.map +1 -1
  28. package/dist/src/utils/root.d.ts +8 -4
  29. package/dist/src/utils/root.d.ts.map +1 -1
  30. package/dist/src/utils/root.js +42 -20
  31. package/dist/src/utils/root.js.map +1 -1
  32. package/dist/src/utils/validate.d.ts +1 -0
  33. package/dist/src/utils/validate.d.ts.map +1 -1
  34. package/dist/src/utils/validate.js +42 -0
  35. package/dist/src/utils/validate.js.map +1 -1
  36. package/package.json +1 -1
@@ -86,8 +86,20 @@ jobs:
86
86
 
87
87
  # --- Commit SHAs: immutable facts for deferred origin resolution.
88
88
  # Capped at 50 to bound the event size and the render-time join.
89
- COMMIT_SHAS=$(git rev-list "${BASE_SHA}..${HEAD_SHA}" 2>/dev/null | head -50 | jq -R . | jq -sc . || echo '[]')
90
- TOTAL_COMMITS=$(git rev-list --count "${BASE_SHA}..${HEAD_SHA}" 2>/dev/null || echo 0)
89
+ #
90
+ # --no-merges matters here. HEAD_SHA is the PR's merge_commit_sha, so the
91
+ # range BASE..HEAD includes GitHub's own merge commit, authored by
92
+ # web-flow on GitHub's servers. codeburn attributes commits made on a
93
+ # developer's machine, so that commit can never appear in the attribution
94
+ # store. Counting it puts a structural ceiling on Attribution Coverage:
95
+ # a fully-onboarded team with 3 PRs and 9 authored commits reported
96
+ # 9 attributed / 12 seen = 75%, when the true coverage was 100%.
97
+ #
98
+ # Excluding every merge commit, not just GitHub's, is the right call for
99
+ # this pair: a merge commit introduces no authored lines, so it is not
100
+ # attributable content on either side of the ratio.
101
+ COMMIT_SHAS=$(git rev-list --no-merges "${BASE_SHA}..${HEAD_SHA}" 2>/dev/null | head -50 | jq -R . | jq -sc . || echo '[]')
102
+ TOTAL_COMMITS=$(git rev-list --no-merges --count "${BASE_SHA}..${HEAD_SHA}" 2>/dev/null || echo 0)
91
103
 
92
104
  # --- Lead time: PR open → merge. From the event payload, not git, so
93
105
  # it is unaffected by rebases and squashes.
@@ -262,14 +262,12 @@ jobs:
262
262
  REPO: ${{ github.repository }}
263
263
  PR_NUMBER: ${{ github.event.pull_request.number }}
264
264
  run: |
265
- # Pre-flight: verify the specific subcommand exists (AWS CLI v2.36+)
266
- if ! aws securityagent start-code-review-job help > /dev/null 2>&1; then
267
- echo "::warning::AWS CLI lacks securityagent code review commands (need v2.36+). Skipping scan."
268
- echo "findings=0" >> "$GITHUB_OUTPUT"
269
- echo "skipped=true" >> "$GITHUB_OUTPUT"
270
- exit 0
271
- fi
272
-
265
+ # Config is read FIRST, on purpose. "Continuum was never deployed" is a
266
+ # deployment choice and may legitimately skip the scan; "Continuum is
267
+ # deployed but the scan could not run" is a failure and must block the
268
+ # merge. Probing the CLI before knowing which case we are in cannot tell
269
+ # them apart, so a missing subcommand used to silently pass the gate on a
270
+ # repo that had opted into scanning.
273
271
  AGENT_SPACE_ID=$(aws ssm get-parameter --name /prism/continuum/agent-space-id --query Parameter.Value --output text 2>/dev/null || echo "")
274
272
  SCAN_BUCKET=$(aws ssm get-parameter --name /prism/continuum/scan-bucket --query Parameter.Value --output text 2>/dev/null || echo "")
275
273
 
@@ -280,6 +278,16 @@ jobs:
280
278
  exit 0
281
279
  fi
282
280
 
281
+ # Continuum IS configured from here on, so every failure below fails
282
+ # closed: scan_error=true and findings=-1, never findings=0.
283
+ if ! aws securityagent start-code-review-job help > /dev/null 2>&1; then
284
+ echo "::error::Continuum is configured but this AWS CLI lacks the securityagent code review commands (need v2.36+)."
285
+ echo " The security scan cannot run, so this PR is not verified. Upgrade the CLI in the workflow."
286
+ echo "scan_error=true" >> "$GITHUB_OUTPUT"
287
+ echo "findings=-1" >> "$GITHUB_OUTPUT"
288
+ exit 0
289
+ fi
290
+
283
291
  REPO_SLUG=$(echo "${REPO}" | tr '/' '-')
284
292
  CODE_REVIEW_ID=$(aws ssm get-parameter --name "/prism/continuum/code-review-id/${REPO_SLUG}" --query Parameter.Value --output text 2>/dev/null || echo "")
285
293
  if [ -z "$CODE_REVIEW_ID" ]; then
@@ -307,10 +315,10 @@ jobs:
307
315
  CODE_REVIEW_ID=$(echo "$CR_OUTPUT" | jq -r '.codeReviewId // empty' 2>/dev/null)
308
316
 
309
317
  if [ -z "$CODE_REVIEW_ID" ]; then
310
- echo "::warning::Bootstrap failed: ${CR_OUTPUT}"
311
- echo " Run 'sudo prism-cli securityagent setup' from your DevBox to create manually."
312
- echo "findings=0" >> "$GITHUB_OUTPUT"
313
- echo "skipped=true" >> "$GITHUB_OUTPUT"
318
+ echo "::error::Could not create the Continuum Code Review resource: ${CR_OUTPUT}"
319
+ echo " Run 'prism-cli securityagent setup' to create it manually."
320
+ echo "scan_error=true" >> "$GITHUB_OUTPUT"
321
+ echo "findings=-1" >> "$GITHUB_OUTPUT"
314
322
  exit 0
315
323
  fi
316
324
 
@@ -325,7 +333,13 @@ jobs:
325
333
  # Diff must be uploaded with .patch extension (API requirement)
326
334
  git diff "${BASE_SHA}..${HEAD_SHA}" > /tmp/changes.patch
327
335
  if [ ! -s /tmp/changes.patch ]; then
336
+ echo "No changes to scan."
337
+ # critical/high must be set explicitly. The gate tests
338
+ # `critical != '0'`, and an unset output is '', which is != '0' in a
339
+ # GitHub expression -- leaving them unset failed the gate on a no-op PR.
328
340
  echo "findings=0" >> "$GITHUB_OUTPUT"
341
+ echo "critical=0" >> "$GITHUB_OUTPUT"
342
+ echo "high=0" >> "$GITHUB_OUTPUT"
329
343
  exit 0
330
344
  fi
331
345
  DIFF_KEY="diffs/${REPO_SLUG}/${PR_NUMBER}/${HEAD_SHA}.patch"
@@ -350,18 +364,26 @@ jobs:
350
364
  done
351
365
 
352
366
  if [ "$STATUS" != "COMPLETED" ]; then
353
- echo "::warning::Continuum scan did not complete (status: ${STATUS}) -- treating as skipped"
354
- echo "findings=0" >> "$GITHUB_OUTPUT"
355
- echo "skipped=true" >> "$GITHUB_OUTPUT"
367
+ echo "::error::Continuum scan did not complete (status: ${STATUS})."
368
+ echo " An incomplete scan is not a clean scan -- failing closed. Re-run, or check the Continuum job logs."
369
+ echo "scan_error=true" >> "$GITHUB_OUTPUT"
370
+ echo "findings=-1" >> "$GITHUB_OUTPUT"
356
371
  exit 0
357
372
  fi
358
373
 
359
374
  # NOTE: list-findings takes agent-space-id + code-review-job-id only.
360
375
  # Response field is 'findingsSummaries', risk field is 'riskLevel'.
361
- FINDINGS_JSON=$(aws securityagent list-findings \
376
+ # No `|| echo '{"findingsSummaries":[]}'` fallback: an API error there is
377
+ # indistinguishable from a clean scan, so it would pass the gate.
378
+ if ! FINDINGS_JSON=$(aws securityagent list-findings \
362
379
  --agent-space-id "${AGENT_SPACE_ID}" \
363
380
  --code-review-job-id "${JOB_ID}" \
364
- --output json 2>/dev/null || echo '{"findingsSummaries":[]}')
381
+ --output json 2>&1); then
382
+ echo "::error::Continuum scan completed but its findings could not be retrieved: ${FINDINGS_JSON}"
383
+ echo "scan_error=true" >> "$GITHUB_OUTPUT"
384
+ echo "findings=-1" >> "$GITHUB_OUTPUT"
385
+ exit 0
386
+ fi
365
387
 
366
388
  TOTAL=$(echo "$FINDINGS_JSON" | jq '.findingsSummaries | length')
367
389
  CRITICAL=$(echo "$FINDINGS_JSON" | jq '[.findingsSummaries[] | select(.riskLevel == "CRITICAL")] | length')
@@ -443,7 +465,7 @@ jobs:
443
465
  fi
444
466
 
445
467
  - name: Fail on eval gate failure
446
- if: ${{ steps.review.outputs.result == 'FAIL' || steps.review.outputs.result == 'ERROR' || (steps.security-gate.outputs.skipped != 'true' && (steps.security-gate.outputs.critical != '0' || steps.security-gate.outputs.high != '0')) }}
468
+ if: ${{ steps.review.outputs.result == 'FAIL' || steps.review.outputs.result == 'ERROR' || steps.security-gate.outputs.scan_error == 'true' || (steps.security-gate.outputs.skipped != 'true' && (steps.security-gate.outputs.critical != '0' || steps.security-gate.outputs.high != '0')) }}
447
469
  env:
448
470
  REVIEW_RESULT: ${{ steps.review.outputs.result }}
449
471
  REVIEW_HIGH: ${{ steps.review.outputs.high }}
@@ -451,6 +473,7 @@ jobs:
451
473
  REVIEW_SUMMARY: ${{ steps.review.outputs.summary }}
452
474
  SEC_CRITICAL: ${{ steps.security-gate.outputs.critical }}
453
475
  SEC_HIGH: ${{ steps.security-gate.outputs.high }}
476
+ SEC_SCAN_ERROR: ${{ steps.security-gate.outputs.scan_error }}
454
477
  run: |
455
478
  if [ "${REVIEW_RESULT}" = "ERROR" ]; then
456
479
  echo "āŒ Eval gate failed closed: review output could not be parsed"
@@ -458,7 +481,10 @@ jobs:
458
481
  echo "āŒ Kiro found ${REVIEW_HIGH:-?} high-severity issues (score: ${REVIEW_SCORE:-?})"
459
482
  echo "Summary: ${REVIEW_SUMMARY}"
460
483
  fi
461
- if [ "${SEC_CRITICAL:-0}" -gt 0 ] || [ "${SEC_HIGH:-0}" -gt 0 ]; then
484
+ if [ "${SEC_SCAN_ERROR}" = "true" ]; then
485
+ echo "āŒ Security gate failed closed: the Continuum scan produced no verdict."
486
+ echo " This PR has NOT been security scanned. Re-run the workflow, or check the Continuum job logs."
487
+ elif [ "${SEC_CRITICAL:-0}" -gt 0 ] || [ "${SEC_HIGH:-0}" -gt 0 ]; then
462
488
  echo "āŒ Continuum found ${SEC_CRITICAL:-0} critical, ${SEC_HIGH:-0} high security findings"
463
489
  fi
464
490
  exit 1
@@ -222,7 +222,7 @@ jobs:
222
222
  \"EventBusName\":\"prism-d1-metrics\",
223
223
  \"Detail\":$(echo "${EVAL_EVENT}" | jq -c '.' | jq -Rs '.')}]"
224
224
 
225
- - name: Upgrade AWS CLI v2 (securityagent code review requires v2.35+)
225
+ - name: Upgrade AWS CLI v2 (securityagent code review requires v2.36+)
226
226
  run: |
227
227
  curl -fsSL "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o /tmp/awscliv2.zip
228
228
  curl -fsSL "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip.sha256" -o /tmp/awscliv2.zip.sha256
@@ -240,14 +240,6 @@ jobs:
240
240
  env:
241
241
  AWS_REGION: us-west-2
242
242
  run: |
243
- # Pre-flight: verify AWS CLI has securityagent subcommand
244
- if ! aws securityagent start-code-review-job help > /dev/null 2>&1; then
245
- echo "::warning::AWS CLI does not support 'securityagent code review' commands after upgrade. Skipping scan."
246
- echo "findings=0" >> "$GITHUB_OUTPUT"
247
- echo "skipped=true" >> "$GITHUB_OUTPUT"
248
- exit 0
249
- fi
250
-
251
243
  echo "::group::Retrieve Continuum config from SSM"
252
244
  AGENT_SPACE_ID=$(aws ssm get-parameter --name /prism/continuum/agent-space-id --query Parameter.Value --output text 2>/dev/null || echo "")
253
245
  SCAN_BUCKET=$(aws ssm get-parameter --name /prism/continuum/scan-bucket --query Parameter.Value --output text 2>/dev/null || echo "")
@@ -262,6 +254,19 @@ jobs:
262
254
  exit 0
263
255
  fi
264
256
 
257
+ # Continuum IS configured from here on, so every failure below fails
258
+ # closed. The CLI probe runs after the config lookup on purpose: before
259
+ # it, "never deployed" and "deployed but cannot scan" are
260
+ # indistinguishable, and the old order silently passed the gate on a repo
261
+ # that had opted into scanning.
262
+ if ! aws securityagent start-code-review-job help > /dev/null 2>&1; then
263
+ echo "::error::Continuum is configured but this AWS CLI lacks the securityagent code review commands (need v2.36+)."
264
+ echo " The security scan cannot run, so this PR is not verified."
265
+ echo "scan_error=true" >> "$GITHUB_OUTPUT"
266
+ echo "findings=-1" >> "$GITHUB_OUTPUT"
267
+ exit 0
268
+ fi
269
+
265
270
  # Fallback for service role if SSM param not yet deployed
266
271
  if [[ -z "$SERVICE_ROLE" ]]; then
267
272
  ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
@@ -296,10 +301,9 @@ jobs:
296
301
  if [[ -z "$CODE_REVIEW_ID" ]]; then
297
302
  echo " āš ļø Bootstrap failed:"
298
303
  echo " $CR_OUTPUT"
299
- echo " Run 'sudo prism-cli securityagent setup' from your DevBox to create manually."
300
- echo " Skipping security scan (non-blocking)."
301
- echo "findings=0" >> "$GITHUB_OUTPUT"
302
- echo "skipped=true" >> "$GITHUB_OUTPUT"
304
+ echo " Run 'prism-cli securityagent setup' to create it manually."
305
+ echo "scan_error=true" >> "$GITHUB_OUTPUT"
306
+ echo "findings=-1" >> "$GITHUB_OUTPUT"
303
307
  exit 0
304
308
  fi
305
309
 
@@ -377,10 +381,18 @@ jobs:
377
381
  fi
378
382
 
379
383
  echo "::group::Retrieve findings"
380
- FINDINGS_JSON=$(aws securityagent list-findings \
384
+ # No empty-array fallback: an API error there is indistinguishable from a
385
+ # clean scan, so it would pass the gate.
386
+ if ! FINDINGS_JSON=$(aws securityagent list-findings \
381
387
  --agent-space-id "${AGENT_SPACE_ID}" \
382
388
  --code-review-job-id "${JOB_ID}" \
383
- --output json 2>/dev/null || echo '{"findingsSummaries":[]}')
389
+ --output json 2>&1); then
390
+ echo "::error::Continuum scan completed but its findings could not be retrieved: ${FINDINGS_JSON}"
391
+ echo "scan_error=true" >> "$GITHUB_OUTPUT"
392
+ echo "findings=-1" >> "$GITHUB_OUTPUT"
393
+ echo "::endgroup::"
394
+ exit 0
395
+ fi
384
396
 
385
397
  TOTAL=$(echo "$FINDINGS_JSON" | jq '.findingsSummaries | length')
386
398
  CRITICAL=$(echo "$FINDINGS_JSON" | jq '[.findingsSummaries[] | select(.riskLevel == "CRITICAL")] | length')
@@ -441,7 +453,7 @@ jobs:
441
453
  fi
442
454
 
443
455
  - name: Fail on eval or security issues
444
- if: steps.eval.outputs.overall_result == 'FAIL' || (steps.security-gate.outputs.findings != '0' && steps.security-gate.outputs.skipped != 'true')
456
+ if: steps.eval.outputs.overall_result == 'FAIL' || steps.security-gate.outputs.scan_error == 'true' || (steps.security-gate.outputs.findings != '0' && steps.security-gate.outputs.skipped != 'true')
445
457
  run: |
446
458
  [[ "${{ steps.eval.outputs.overall_result }}" == "FAIL" ]] && echo "āŒ Eval gate failed"
447
459
  if [[ "${{ steps.security-gate.outputs.scan_error }}" == "true" ]]; then
@@ -74,8 +74,15 @@ prism-ai-metrics:
74
74
  HEAD_SHA="${CI_COMMIT_SHA}"
75
75
 
76
76
  # --- Commit SHAs: immutable facts for deferred origin resolution.
77
- COMMIT_SHAS=$(git rev-list "${BASE_SHA}..${HEAD_SHA}" 2>/dev/null | head -50 | jq -R . | jq -sc . || echo '[]')
78
- TOTAL_COMMITS=$(git rev-list --count "${BASE_SHA}..${HEAD_SHA}" 2>/dev/null || echo "1")
77
+ #
78
+ # --no-merges for the same reason as the GitHub workflow: under a
79
+ # merge-commit strategy CI_COMMIT_SHA is the merge commit GitLab created,
80
+ # which no developer machine authored and codeburn can therefore never
81
+ # attribute. Counting it caps Attribution Coverage below 100% for a fully
82
+ # onboarded team. Harmless under squash or fast-forward, where the range
83
+ # holds no merge commits to exclude.
84
+ COMMIT_SHAS=$(git rev-list --no-merges "${BASE_SHA}..${HEAD_SHA}" 2>/dev/null | head -50 | jq -R . | jq -sc . || echo '[]')
85
+ TOTAL_COMMITS=$(git rev-list --no-merges --count "${BASE_SHA}..${HEAD_SHA}" 2>/dev/null || echo "1")
79
86
 
80
87
  # --- Lead time: MR open → now (this job runs on the post-merge push).
81
88
  LEAD_TIME_SECONDS=0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  DynamoDBClient,
3
- QueryCommand,
3
+ GetItemCommand,
4
4
  ScanCommand,
5
5
  } from '@aws-sdk/client-dynamodb';
6
6
  import {
@@ -14,6 +14,9 @@ const eventBridgeClient = new EventBridgeClient({});
14
14
  const EVENTS_TABLE = process.env.EVENTS_TABLE!;
15
15
  const METADATA_TABLE = process.env.METADATA_TABLE!;
16
16
  const EVENT_BUS_NAME = process.env.EVENT_BUS_NAME!;
17
+ // Optional: unset when the OTEL collector is skipped, in which case no
18
+ // attribution exists to join against and AI origin stays 'unknown'.
19
+ const AI_USAGE_TABLE = process.env.AI_USAGE_TABLE;
17
20
 
18
21
  interface SecurityAgentPayload {
19
22
  findings: Array<{
@@ -177,55 +180,85 @@ async function lookupTeamId(repo: string): Promise<string> {
177
180
  }
178
181
  }
179
182
 
183
+ /**
184
+ * Candidate `REPO#` partition keys for one repository name.
185
+ *
186
+ * The two sides of this join spell the repo differently and nothing normalizes
187
+ * either. codeburn sets the `git.repo` span attribute from the git remote, so
188
+ * the attribution store holds a host-qualified path (`github.com/owner/name`).
189
+ * CI sends `GITHUB_REPOSITORY`, which is bare (`owner/name`). A single GetItem
190
+ * on whichever form the caller happened to pass would miss roughly half the
191
+ * time — and miss silently, since a missing item is indistinguishable from an
192
+ * unattributed commit.
193
+ *
194
+ * Rather than guess, try the value as given and then the plausible
195
+ * translations: add a host if it looks bare, strip one if it looks qualified.
196
+ */
197
+ function repoKeyCandidates(repo: string): string[] {
198
+ const bare = repo.replace(/^https?:\/\//, '').replace(/\.git$/, '').replace(/\/+$/, '');
199
+ const candidates = [bare];
200
+ const segments = bare.split('/');
201
+ if (segments.length === 2) {
202
+ // owner/name → try the hosts codeburn would have recorded.
203
+ candidates.push(`github.com/${bare}`, `gitlab.com/${bare}`);
204
+ } else if (segments.length > 2) {
205
+ // host/owner/name → try dropping the host.
206
+ candidates.push(segments.slice(1).join('/'));
207
+ }
208
+ return [...new Set(candidates)];
209
+ }
210
+
211
+ /**
212
+ * Resolves whether the code a finding lands on was AI-written.
213
+ *
214
+ * Reads the attribution store, which is the only place that answer now lives.
215
+ * This previously queried the events table for `prism.d1.commit` and counted
216
+ * ai vs human across the last 7 days — but nothing emits `prism.d1.commit`.
217
+ * The git hooks that were once expected to only ever wrote commit-message
218
+ * trailers, so the query never matched and every finding was tagged 'unknown',
219
+ * silently, with the CISO dashboard's AI-code-risk panel downstream of it.
220
+ *
221
+ * The per-commit verdict is frozen onto the COMMIT# item at ingest by
222
+ * otel-receiver (`ai_origin`), so a point lookup is enough — no span join, and
223
+ * no dependence on a span TTL that is shorter than the commit TTL.
224
+ */
180
225
  async function lookupAiOrigin(
181
226
  teamId: string,
182
227
  repo: string,
183
228
  commitSha: string | null,
184
229
  prNumber: number | null,
185
230
  ): Promise<'ai-generated' | 'ai-assisted' | 'human' | 'unknown'> {
186
- if (!commitSha && !prNumber) return 'unknown';
187
-
188
- try {
189
- // Query recent commit events for this repo to find AI origin
190
- const pk = `${teamId}#${repo}`;
191
- const now = new Date();
192
- const lookback = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000); // 7 days
193
-
194
- const result = await dynamoClient.send(
195
- new QueryCommand({
196
- TableName: EVENTS_TABLE,
197
- KeyConditionExpression: 'pk = :pk AND sk >= :start',
198
- FilterExpression: 'detail_type = :dt',
199
- ExpressionAttributeValues: {
200
- ':pk': { S: pk },
201
- ':start': { S: lookback.toISOString() },
202
- ':dt': { S: 'prism.d1.commit' },
203
- },
204
- ScanIndexForward: false, // Most recent first
205
- Limit: 20,
206
- }),
207
- );
231
+ // A PR number alone cannot identify a commit in the attribution store, whose
232
+ // key is REPO#<repo>/COMMIT#<sha>. Returning 'unknown' is correct here rather
233
+ // than guessing from the repo's recent history.
234
+ if (!commitSha) return 'unknown';
235
+ if (!AI_USAGE_TABLE) return 'unknown';
208
236
 
209
- if (result.Items && result.Items.length > 0) {
210
- // Count AI vs human commits to determine predominant origin
211
- let aiCount = 0;
212
- let humanCount = 0;
213
- for (const item of result.Items) {
214
- const data = JSON.parse(item.data?.S ?? '{}');
215
- const origin = data.ai_context?.origin ?? 'human';
216
- if (origin === 'ai-generated' || origin === 'ai-assisted') {
217
- aiCount++;
218
- } else {
219
- humanCount++;
220
- }
221
- }
222
- if (aiCount > humanCount) return 'ai-assisted';
223
- if (humanCount > aiCount) return 'human';
237
+ for (const candidate of repoKeyCandidates(repo)) {
238
+ try {
239
+ const result = await dynamoClient.send(
240
+ new GetItemCommand({
241
+ TableName: AI_USAGE_TABLE,
242
+ Key: {
243
+ pk: { S: `REPO#${candidate}` },
244
+ sk: { S: `COMMIT#${commitSha}` },
245
+ },
246
+ ProjectionExpression: 'ai_origin',
247
+ }),
248
+ );
249
+ const origin = result.Item?.ai_origin?.S;
250
+ if (origin === 'ai-generated' || origin === 'human') return origin;
251
+ // Item exists but carries no frozen verdict (written before write-time
252
+ // resolution). Treat as unresolved rather than trying another key.
253
+ if (result.Item) return 'unknown';
254
+ } catch (err) {
255
+ console.error(`AI origin lookup failed for REPO#${candidate}:`, err);
256
+ return 'unknown';
224
257
  }
225
-
226
- return 'unknown';
227
- } catch (err) {
228
- console.error('Failed to look up AI origin:', err);
229
- return 'unknown';
230
258
  }
259
+
260
+ // No attribution for this commit — the author's machine is not onboarded to
261
+ // codeburn sync. Distinct from 'human', which is a positive verdict.
262
+ console.log(`No attribution found for ${repo}@${commitSha} (team ${teamId}, PR ${prNumber ?? 'n/a'})`);
263
+ return 'unknown';
231
264
  }
@@ -839,6 +839,10 @@ export class MetricsPipelineStack extends cdk.Stack {
839
839
  EVENTS_TABLE: this.eventsTable.tableName,
840
840
  METADATA_TABLE: this.metadataTable.tableName,
841
841
  EVENT_BUS_NAME: this.eventBus.eventBusName,
842
+ // Findings are tagged AI vs human by looking the commit up in the
843
+ // attribution store. Left unset when the OTEL collector is skipped,
844
+ // in which case there is no attribution and origin stays 'unknown'.
845
+ AI_USAGE_TABLE: this.aiUsageTable.tableName,
842
846
  },
843
847
  logRetention: logs.RetentionDays.ONE_MONTH,
844
848
  description: 'Normalizes AWS Security Agent findings and emits to PRISM pipeline',
@@ -846,6 +850,10 @@ export class MetricsPipelineStack extends cdk.Stack {
846
850
 
847
851
  this.eventsTable.grantReadData(securityAgentProcessor);
848
852
  this.metadataTable.grantReadData(securityAgentProcessor);
853
+ // Read-only: the processor resolves a finding's AI origin from the frozen
854
+ // ai_origin on the COMMIT# item. grantReadData also grants kms:Decrypt on
855
+ // the table's customer-managed key, which a bare IAM action would not.
856
+ this.aiUsageTable.grantReadData(securityAgentProcessor);
849
857
  this.eventBus.grantPutEventsTo(securityAgentProcessor);
850
858
 
851
859
  // Security Remediation Tracker
@@ -1 +1 @@
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,wBA8CE"}
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,wBAwDE"}
@@ -74,6 +74,15 @@ export default {
74
74
  }
75
75
  // Determine mode
76
76
  const mode = opts.mode || await prompt('Eval mode (kiro = recommended, bedrock = legacy)', 'kiro');
77
+ // Validated rather than falling through to bedrock. Both modes write the same
78
+ // workflow file, so a typo'd mode used to install the other gate silently --
79
+ // surfacing only as an unexpected Bedrock bill, or as a kiro gate with no
80
+ // KIRO_API_KEY. install-github-workflows rejects the same set.
81
+ if (mode !== 'kiro' && mode !== 'bedrock') {
82
+ console.error(`Error: unknown --mode "${mode}".`);
83
+ console.error(' Expected one of: kiro, bedrock');
84
+ process.exit(1);
85
+ }
77
86
  if (mode === 'kiro') {
78
87
  await installKiroMode(gitRoot, opts);
79
88
  }
@@ -1 +1 @@
1
- {"version":3,"file":"install-eval-harness.js","sourceRoot":"","sources":["../../../../src/commands/bootstrapper/install-eval-harness.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"install-eval-harness.js","sourceRoot":"","sources":["../../../../src/commands/bootstrapper/install-eval-harness.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,7 @@ declare const _default: {
6
6
  default: string;
7
7
  }[];
8
8
  action(opts: {
9
+ mode?: string;
9
10
  region?: string;
10
11
  outputDir: string;
11
12
  }): Promise<void>;
@@ -1 +1 @@
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
+ {"version":3,"file":"install-github-workflows.d.ts","sourceRoot":"","sources":["../../../../src/commands/bootstrapper/install-github-workflows.ts"],"names":[],"mappings":";;;;;;;iBAoCqB;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;;AAP1E,wBA8EE"}
@@ -1,23 +1,63 @@
1
- import { mkdirSync, readFileSync, writeFileSync, readdirSync } from 'node:fs';
1
+ import { existsSync, 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
+ import { applyRegion, findDefaultRegionRefs, DEFAULT_REGION } from '../../utils/region.js';
5
+ /**
6
+ * The eval gate ships as one asset per mode, and exactly one may be installed.
7
+ *
8
+ * Both files declare `name: PRISM Eval Gate` with the same `pull_request`
9
+ * triggers, so installing both -- which this command used to do, by copying every
10
+ * asset -- produces two same-named check runs on every PR, one billing Bedrock
11
+ * and one billing the Kiro API.
12
+ *
13
+ * Both modes are written to a single output name, matching what
14
+ * `install-eval-harness --mode <mode>` does, so the two installers converge on
15
+ * the same file instead of leaving a mode-specific name behind.
16
+ */
17
+ const EVAL_GATE_ASSETS = {
18
+ kiro: 'prism-eval-gate-kiro.yml',
19
+ bedrock: 'prism-eval-gate.yml',
20
+ };
21
+ const EVAL_GATE_OUTPUT = 'prism-eval-gate.yml';
22
+ /** Rules or rubrics each mode's gate reads, installed separately. */
23
+ const MODE_COMPANION = {
24
+ kiro: '.kiro/steering/code-review.md',
25
+ bedrock: '.prism/eval-harness/ (run-eval.sh + rubrics)',
26
+ };
5
27
  export default {
6
28
  description: 'Install GitHub Actions workflow templates into the current repo',
7
29
  options: [
8
- { flags: '--region <region>', description: 'AWS region for EventBridge/CloudWatch', default: 'us-west-2' },
30
+ { flags: '--mode <mode>', description: 'Eval gate mode: "kiro" (default, headless kiro-cli) or "bedrock" (legacy rubrics). Only one gate is installed', default: 'kiro' },
31
+ { flags: '--region <region>', description: 'AWS region for EventBridge/CloudWatch; must match setup-github-oidc', default: DEFAULT_REGION },
9
32
  { flags: '--output-dir <dir>', description: 'Output directory', default: '.github/workflows' },
10
33
  ],
11
34
  async action(opts) {
12
- const region = opts.region || 'us-west-2';
35
+ const region = opts.region || DEFAULT_REGION;
13
36
  const outputDir = opts.outputDir;
37
+ // Validated rather than defaulted: silently treating an unrecognised mode as
38
+ // bedrock would install the gate the user did not ask for, and the failure
39
+ // only shows up as an unexpected Bedrock bill or a missing KIRO_API_KEY.
40
+ const mode = opts.mode || 'kiro';
41
+ if (!(mode in EVAL_GATE_ASSETS)) {
42
+ console.error(`Error: unknown --mode "${mode}".`);
43
+ console.error(` Expected one of: ${Object.keys(EVAL_GATE_ASSETS).join(', ')}`);
44
+ process.exit(1);
45
+ }
14
46
  console.log(`\nšŸ“¦ Installing GitHub Actions workflows`);
47
+ console.log(` Mode: ${mode} eval gate`);
15
48
  console.log(` Region: ${region}`);
16
49
  console.log(` Output: ${outputDir}/\n`);
17
50
  mkdirSync(outputDir, { recursive: true });
18
51
  const assetDir = getAssetPath(import.meta.url, 'github-workflows/prism-ai-metrics.yml').replace('/prism-ai-metrics.yml', '');
19
52
  const files = readdirSync(assetDir).filter(f => f.endsWith('.yml'));
53
+ const gateAssets = new Set(Object.values(EVAL_GATE_ASSETS));
54
+ const selectedGate = EVAL_GATE_ASSETS[mode];
55
+ let installed = 0;
20
56
  for (const file of files) {
57
+ // Skip the other mode's gate entirely.
58
+ if (gateAssets.has(file) && file !== selectedGate)
59
+ continue;
60
+ const outName = gateAssets.has(file) ? EVAL_GATE_OUTPUT : file;
21
61
  let content = readFileSync(join(assetDir, file), 'utf-8');
22
62
  content = applyRegion(content, region);
23
63
  const stragglers = findDefaultRegionRefs(content, file);
@@ -25,14 +65,34 @@ export default {
25
65
  console.warn(` ⚠ ${file}: ${stragglers.length} unconverted region reference(s):`);
26
66
  stragglers.forEach(s => console.warn(` ${s}`));
27
67
  }
28
- writeFileSync(join(outputDir, file), content);
29
- console.log(` āœ“ ${file}`);
68
+ writeFileSync(join(outputDir, outName), content);
69
+ console.log(` āœ“ ${outName}${file === outName ? '' : ` (${mode} mode, from ${file})`}`);
70
+ installed++;
30
71
  }
31
- console.log(`\nāœ… Installed ${files.length} workflow files to ${outputDir}/`);
72
+ // A pre-mode install of this command copied every asset, so an upgrading repo
73
+ // can still hold the other gate under its asset name. Reported rather than
74
+ // deleted: it is a tracked file in the user's repo, not ours to remove.
75
+ const stale = join(outputDir, EVAL_GATE_ASSETS.kiro);
76
+ if (EVAL_GATE_ASSETS.kiro !== EVAL_GATE_OUTPUT && existsSync(stale)) {
77
+ console.warn(`\n ⚠ ${stale} is also present, left over from an earlier install.`);
78
+ console.warn(` It declares the same check name and trigger as ${EVAL_GATE_OUTPUT},`);
79
+ console.warn(` so both gates would run on every PR. Remove it:`);
80
+ console.warn(` rm ${stale}`);
81
+ }
82
+ console.log(`\nāœ… Installed ${installed} workflow files to ${outputDir}/`);
32
83
  console.log(`\nNext steps:`);
33
- console.log(` 1. Run: prism-cli bootstrapper setup-github-oidc`);
84
+ console.log(` 1. Run: prism-cli bootstrapper setup-github-oidc --region ${region}`);
34
85
  console.log(` 2. Add repository secret PRISM_METRICS_ROLE_ARN in GitHub`);
35
- console.log(` 3. Commit and push the workflow files`);
86
+ if (mode === 'kiro') {
87
+ console.log(` 3. Add repository secret KIRO_API_KEY (https://app.kiro.dev → Settings → API Keys)`);
88
+ console.log(` 4. Run: prism-cli bootstrapper install-eval-harness --mode kiro`);
89
+ console.log(` — installs ${MODE_COMPANION.kiro}, the rules the gate reviews against`);
90
+ }
91
+ else {
92
+ console.log(` 3. Run: prism-cli bootstrapper install-eval-harness --with-rubrics`);
93
+ console.log(` — installs ${MODE_COMPANION.bedrock}, which the gate reads`);
94
+ }
95
+ console.log(` ${mode === 'kiro' ? '5' : '4'}. Commit and push the workflow files`);
36
96
  console.log('');
37
97
  },
38
98
  };
@@ -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;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
+ {"version":3,"file":"install-github-workflows.js","sourceRoot":"","sources":["../../../../src/commands/bootstrapper/install-github-workflows.ts"],"names":[],"mappings":"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"}