carson 1.0.0 → 2.6.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.
@@ -48,7 +48,6 @@ module Carson
48
48
  audit_state = "block" if default_branch_baseline.fetch( :status ) == "block"
49
49
  audit_state = "attention" if audit_state == "ok" && default_branch_baseline.fetch( :status ) != "ok"
50
50
  scope_guard = print_scope_integrity_guard
51
- audit_state = "block" if scope_guard.fetch( :split_required )
52
51
  audit_state = "attention" if audit_state == "ok" && scope_guard.fetch( :status ) == "attention"
53
52
  write_and_print_pr_monitor_report(
54
53
  report: monitor_report.merge(
@@ -279,7 +278,7 @@ module Carson
279
278
  local_rubocop_path = File.join( repo_root, ".rubocop.yml" )
280
279
  if File.file?( local_rubocop_path )
281
280
  report[ :status ] = "block"
282
- report[ :reason ] = "repo-local RuboCop config is forbidden: #{relative_path( local_rubocop_path )}; remove it and use ~/AI/CODING/rubocop.yml."
281
+ report[ :reason ] = "repo-local RuboCop config is forbidden: #{relative_path( local_rubocop_path )}; remove it and use ~/.carson/lint/rubocop.yml."
283
282
  report[ :exit_code ] = EXIT_BLOCK
284
283
  puts_line "lint_#{language}_status: block"
285
284
  puts_line "lint_#{language}_reason: #{report.fetch( :reason )}"
@@ -297,7 +296,7 @@ module Carson
297
296
  report[ :exit_code ] = EXIT_BLOCK
298
297
  puts_line "lint_#{language}_status: block"
299
298
  puts_line "lint_#{language}_reason: #{report.fetch( :reason )}"
300
- puts_line "ACTION: run carson lint setup --source <path-or-git-url> to prepare ~/AI/CODING policy files."
299
+ puts_line "ACTION: run carson lint setup --source <path-or-git-url> to prepare ~/.carson/lint policy files."
301
300
  return report
302
301
  end
303
302
 
@@ -403,9 +402,13 @@ module Carson
403
402
  check_runs_total: 0,
404
403
  failing_count: 0,
405
404
  pending_count: 0,
405
+ advisory_failing_count: 0,
406
+ advisory_pending_count: 0,
406
407
  no_check_evidence: false,
407
408
  failing: [],
408
- pending: []
409
+ pending: [],
410
+ advisory_failing: [],
411
+ advisory_pending: []
409
412
  }
410
413
  unless gh_available?
411
414
  report[ :status ] = "skipped"
@@ -443,15 +446,23 @@ module Carson
443
446
  )
444
447
  check_runs = Array( check_runs_payload[ "check_runs" ] )
445
448
  failing, pending = partition_default_branch_check_runs( check_runs: check_runs )
449
+ advisory_names = config.audit_advisory_check_names
450
+ critical_failing, advisory_failing = separate_advisory_check_entries( entries: failing, advisory_names: advisory_names )
451
+ critical_pending, advisory_pending = separate_advisory_check_entries( entries: pending, advisory_names: advisory_names )
446
452
  report[ :check_runs_total ] = check_runs.count
447
- report[ :failing ] = normalise_default_branch_check_entries( entries: failing )
448
- report[ :pending ] = normalise_default_branch_check_entries( entries: pending )
453
+ report[ :failing ] = normalise_default_branch_check_entries( entries: critical_failing )
454
+ report[ :pending ] = normalise_default_branch_check_entries( entries: critical_pending )
455
+ report[ :advisory_failing ] = normalise_default_branch_check_entries( entries: advisory_failing )
456
+ report[ :advisory_pending ] = normalise_default_branch_check_entries( entries: advisory_pending )
449
457
  report[ :failing_count ] = report.fetch( :failing ).count
450
458
  report[ :pending_count ] = report.fetch( :pending ).count
459
+ report[ :advisory_failing_count ] = report.fetch( :advisory_failing ).count
460
+ report[ :advisory_pending_count ] = report.fetch( :advisory_pending ).count
451
461
  report[ :no_check_evidence ] = report.fetch( :workflows_total ).positive? && report.fetch( :check_runs_total ).zero?
452
462
  report[ :status ] = "block" if report.fetch( :failing_count ).positive?
453
463
  report[ :status ] = "block" if report.fetch( :pending_count ).positive?
454
464
  report[ :status ] = "block" if report.fetch( :no_check_evidence )
465
+ report[ :status ] = "attention" if report.fetch( :status ) == "ok" && ( report.fetch( :advisory_failing_count ).positive? || report.fetch( :advisory_pending_count ).positive? )
455
466
  puts_line "default_branch_repository: #{report.fetch( :repository )}"
456
467
  puts_line "default_branch_name: #{report.fetch( :default_branch )}"
457
468
  puts_line "default_branch_head_sha: #{report.fetch( :head_sha )}"
@@ -459,8 +470,12 @@ module Carson
459
470
  puts_line "default_branch_check_runs_total: #{report.fetch( :check_runs_total )}"
460
471
  puts_line "default_branch_failing: #{report.fetch( :failing_count )}"
461
472
  puts_line "default_branch_pending: #{report.fetch( :pending_count )}"
473
+ puts_line "default_branch_advisory_failing: #{report.fetch( :advisory_failing_count )}"
474
+ puts_line "default_branch_advisory_pending: #{report.fetch( :advisory_pending_count )}"
462
475
  report.fetch( :failing ).each { |entry| puts_line "default_branch_check_fail: #{entry.fetch( :workflow )} / #{entry.fetch( :name )} #{entry.fetch( :link )}".strip }
463
476
  report.fetch( :pending ).each { |entry| puts_line "default_branch_check_pending: #{entry.fetch( :workflow )} / #{entry.fetch( :name )} #{entry.fetch( :link )}".strip }
477
+ report.fetch( :advisory_failing ).each { |entry| puts_line "default_branch_check_advisory_fail: #{entry.fetch( :workflow )} / #{entry.fetch( :name )} (advisory) #{entry.fetch( :link )}".strip }
478
+ report.fetch( :advisory_pending ).each { |entry| puts_line "default_branch_check_advisory_pending: #{entry.fetch( :workflow )} / #{entry.fetch( :name )} (advisory) #{entry.fetch( :link )}".strip }
464
479
  if report.fetch( :no_check_evidence )
465
480
  puts_line "ACTION: default branch has workflow files but no check-runs; align workflow triggers and branch protection check names."
466
481
  end
@@ -525,6 +540,14 @@ module Carson
525
540
  [ failing, pending ]
526
541
  end
527
542
 
543
+ # Separates check-run entries into critical and advisory buckets based on configured advisory names.
544
+ def separate_advisory_check_entries( entries:, advisory_names: )
545
+ advisory, critical = Array( entries ).partition do |entry|
546
+ advisory_names.include?( entry[ "name" ].to_s.strip )
547
+ end
548
+ [ critical, advisory ]
549
+ end
550
+
528
551
  # Failing means completed with a non-successful conclusion.
529
552
  def default_branch_check_run_failing?( entry: )
530
553
  status = entry[ "status" ].to_s.strip.downcase
@@ -701,11 +724,11 @@ module Carson
701
724
  scope.fetch( :unmatched_paths ).each { |path| puts_line "unmatched_path: #{path}" }
702
725
  puts_line "violating_files_count: #{scope.fetch( :violating_files ).count}"
703
726
  scope.fetch( :violating_files ).each { |path| puts_line "violating_file: #{path} (group=#{scope.fetch( :grouped_paths ).fetch( path )})" }
704
- puts_line "checklist_single_business_intent: #{scope.fetch( :split_required ) ? 'needs_review' : 'pass'}"
705
- puts_line "checklist_single_scope_group: #{scope.fetch( :split_required ) ? 'needs_split' : 'pass'}"
706
- puts_line "checklist_cross_boundary_changes_justified: #{( scope.fetch( :split_required ) || scope.fetch( :misc_present ) ) ? 'needs_explanation' : 'pass'}"
727
+ puts_line "checklist_single_business_intent: pass"
728
+ puts_line "checklist_single_scope_group: #{scope.fetch( :split_required ) ? 'advisory' : 'pass'}"
729
+ puts_line "checklist_cross_boundary_changes_justified: #{( scope.fetch( :split_required ) || scope.fetch( :misc_present ) ) ? 'advisory' : 'pass'}"
707
730
  if scope.fetch( :split_required )
708
- puts_line "ACTION: split/re-branch is required before commit; multiple module groups detected."
731
+ puts_line "ACTION: multiple module groups detected (informational only)."
709
732
  elsif scope.fetch( :misc_present )
710
733
  puts_line "ACTION: unmatched paths detected; classify via scope.path_groups for stricter module checks."
711
734
  else