Skip to content

fix: converge governance gates and cognitive security contracts#22298

Closed
BrianCLong wants to merge 19 commits intomainfrom
fix/golden-main-governance-convergence-20260331
Closed

fix: converge governance gates and cognitive security contracts#22298
BrianCLong wants to merge 19 commits intomainfrom
fix/golden-main-governance-convergence-20260331

Conversation

@BrianCLong
Copy link
Copy Markdown
Owner

@BrianCLong BrianCLong commented Mar 31, 2026

Summary

Converges the current governance/CI hardening stack into a single merge vehicle that aligns required-check authority files, strengthens workflow-policy enforcement, restores deterministic branch-protection verification behavior in restricted PR contexts, and introduces the first repo-native Summit Cognitive containment, attestation, and decision-validity contracts.

Supersedes the fragmented governance/CI slice that was previously spread across the 2229x PR cluster.

Risk & Surface (Required)

Risk Level (Select one):

  • risk:low (Docs, comments, safe refactors)
  • risk:medium (Feature flags, backward-compatible changes)
  • risk:high (Database migrations, auth changes, critical path)
  • risk:release-blocking (Critical fixes only)

Surface Area (Select all that apply):

  • area:client
  • area:server
  • area:docs
  • area:infra
  • area:ci
  • area:policy

Assumption Ledger

  • Assumptions: Existing workflow inventory remains legacy-heavy, so policy enforcement must fail closed for new or widened PR-facing workflows without exploding on untouched historical files.
  • Ambiguities: Live branch-protection reads remain permission-constrained in some PR contexts, so convergence validation defers those reads outside trusted GitHub-token scopes.
  • Tradeoffs: This lands the authority convergence and new contract surfaces in one branch to stop queue fragmentation, at the cost of a larger-than-ideal governance PR.
  • Stop Condition: Stop if required-check authority files drift again, metadata validation fails, or focused governance/security verifiers stop passing locally.

Execution Governor & Customer Impact

  • Single Product Mode: Respects active product (FactFlow) or includes .exec-override.
  • Frozen Code: Does not touch frozen products without override.
  • Customer Impact: Positive. Tightens protected-branch governance, adds portable decision-validity/attestation contracts, and reduces CI false negatives on workflow-policy and branch-protection checks.
  • Rollback Plan: Revert commit 3e9794d9af to restore the prior governance baseline; if needed, selectively revert workflow-policy and required-check authority files first to reopen queue movement.

Evidence Bundle

  • Tests: New or updated tests passing?
  • Screenshots: Attached for UI changes?
  • Evidence Generated: Bundle attached or linked?
  • Prompt Hash: prompts/registry.yaml updated (if prompts changed)?

Investigation Trust Doctrine Checklist

  • Deterministic artifact produced.
  • Fixture added or updated.
  • Included in trust manifest.
  • Included in signed trust bundle.
  • Derivation proof exposed (if user-facing).

Security Impact

Green CI Contract Checklist

  • Lint: Ran pnpm lint locally.
  • Tests: Ran pnpm test:unit locally.
  • Determinism: No leaked singletons or open handles.
  • Evidence: Added at least one test case or verification step.

CI & Merge Train Rules

If CI is Blocked:

  • Docs/Metadata PRs may proceed.
  • Behavior changes must wait for green CI.
  • Do not bypass gates without written approval from Release Captain.

Verification

  • Automated Test
  • Manual Verification
  • Snapshot / Screenshot

Focused local verification completed:

  • node scripts/ci/verify_required_checks_contract.mjs
  • node scripts/ci/verify_security_gate.mjs
  • node --test scripts/ci/__tests__/verify_security_gate.test.mjs
  • node --test scripts/ci/__tests__/governance_mutation_guard.test.mjs
  • node scripts/check_branch_protection_convergence.mjs (skip path without GitHub token)
  • Workflow YAML parse on _policy-enforcer.yml, pr-preview.yml, pr-preview-cleanup.yml
  • Local policy-enforcer emulation for changed workflows: no violations
  • git diff --check
{
  "agent_id": "codex",
  "task_id": "governance-gates-cognitive-security-convergence-20260331",
  "prompt_hash": "7a6ce2a5cd05d795558d12d50b935607f9a85587ce8d6be87a4aafd576584993",
  "domains": ["governance", "ci", "documentation", "security", "policy"],
  "verification_tiers": ["B", "C"],
  "debt_delta": 0,
  "declared_scope": {
    "paths": [
      ".github/",
      "docs/",
      "governance/",
      "package.json",
      "policies/",
      "prompts/",
      "schemas/",
      "scripts/"
    ],
    "domains": ["governance", "ci", "documentation", "security", "policy"]
  },
  "allowed_operations": ["create", "edit"]
}

Summary by CodeRabbit

  • New Features

    • Added admissibility and security gates for artifact attestation and deployment checks
    • Introduced failure containment/isolation gates and a Decision Validity attestation flow
  • CI/CD Updates

    • Consolidated and updated required merge checks to attestation- and security-first gates
    • Pinned third-party CI actions for reproducible runs; new workflow verifiers and evidence outputs
  • Documentation

    • Large set of new governance, ops, standards, and playbook docs (decision, evidence, and protocol specs)
  • Governance & Policy

    • Stricter branch protection and new containment, rollout, and verified-property policies

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 31, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2822496a-d0e4-4aa2-85e7-45bfe2110b57

📥 Commits

Reviewing files that changed from the base of the PR and between b19e8eb and 08513a9.

📒 Files selected for processing (21)
  • .github/workflows/_reusable-ci.yml
  • .github/workflows/branch-protection-drift.yml
  • .github/workflows/build.yml
  • .github/workflows/business-integrity.yml
  • .github/workflows/ci-drift-sentinel.yml
  • .github/workflows/ci-guard.yml
  • .github/workflows/ci-security.yml
  • .github/workflows/ci.yml
  • .github/workflows/daily-benchmarks.yml
  • .github/workflows/dataset-flywheel.yml
  • .github/workflows/drift-sentinel.yml
  • .github/workflows/evidence-ledger.yml
  • .github/workflows/ga-verify.yml
  • .github/workflows/learning-ci-example.yml
  • .github/workflows/pr-fast.yml
  • .github/workflows/workflow-lint.yml
  • .repoos/control/spec.json
  • .repoos/scripts/ci/validate_schemas.mjs
  • scripts/ci/check_branch_protection_drift.mjs
  • scripts/ci/check_determinism.mjs
  • scripts/ci/check_determinism.sh

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting


Walkthrough

Adds a decision-validity and admissibility verification stack across CI, governance, runtime, and docs: new verification workflows and scripts, Kyverno/Argo deployment gates, failure-containment policies/schemas, evidence/attestation bundle formats, admissibility evaluation code/tests, and many governance/ops documentation artifacts.

Changes

Cohort / File(s) Summary
Governance & required-checks
/.github/merge-queue-config.json, /.github/required-checks.yml, governance/ga/required-checks.yaml, governance/branch-protection.required.json, docs/governance/REQUIRED_CHECKS_CONTRACT.yml
Replaced legacy CI check contexts with namespaced checks (ci-guard / attestation-bundle-verifier, merge-surge / merge-queue, merge-surge / pr-fast, security-gates / gate) and aligned branch-protection/required-checks manifests.
CI workflows – new gates
.github/workflows/admissibility-gate.yml, .github/workflows/ci-guard.yml, .github/workflows/security-gates.yml, .github/workflows/failure-domain-declaration.yml, .github/workflows/failure-isolation.yml, .github/workflows/failure-semantics.yml
Added workflows for admissibility, attestation verification, security gates, and failure-containment validations with evidence artifact generation.
CI workflows – maintenance & pins
.github/workflows/... (multiple files), /.github/workflows/_policy-enforcer.yml, /.github/workflows/_reusable-ci.yml
Pinned third‑party actions to commit SHAs, standardized pnpm/setup-node usage, added workflow permissions/concurrency, and improved policy-enforcer git-diff logic.
Verification tooling & scripts
scripts/ci/verify_summit_attestation_bundle.mjs, scripts/ci/verify_security_gate.mjs, scripts/ci/verify_required_checks_contract.mjs, scripts/ci/verify_branch_protection.mjs, scripts/ci/verify_failure_semantics.mjs, scripts/ci/verify-admissibility.ts, scripts/ci/verify-sbom-signature.sh
New/updated verifiers that parse workflows/policies/attestation bundles, produce JSON reports/metrics/stamps, and enforce deterministic checks.
Evidence builders & generators
scripts/ci/build_admissibility_evidence.mjs, scripts/ci/generate-admissibility-bundle.ts, scripts/ci/check_failure_domains.mjs, scripts/ci/check_failure_isolation.mjs
Added scripts to produce admissibility evidence, build attestation bundles, and validate/emit failure-domain/isolation reports.
Admissibility library & tests
lib/admissibility.ts, tests/ci/admissibility.test.mts, scripts/ci/__tests__/*
Introduced typed admissibility evaluation, unit tests, and CI test cases covering attestation and security gate verifiers.
Kubernetes & Argo enforcement
k8s/policies/kyverno-admissibility-enforcement.yaml, k8s/policies/kyverno-enforce-admissible-images.yaml, k8s/argo/admissibility-presync-check.yaml, k8s/base/kustomization.yaml, k8s/server-deployment.yaml
Added Kyverno ClusterPolicies enforcing admissibility labels, image attestation/signature checks, and ArgoCD pre-sync check resources.
Helm / charts
charts/companyos/templates/admissibility-presync-job.yaml, deploy/helm/summit/templates/admissibility-presync-job.yaml
Added PreSync Job templates that assert admissibility verdict and evidence digest prior to deploy.
Policies & configs
policies/ops/*.yaml, policies/security/security_gates.yml, policy/admissibility/prohibited-dependencies.json, policy/actions-allowlist.json
Added failure-domain/rollout/containment-slo/verified-properties policies, updated security gate tool mappings, prohibited-deps list, and actions allowlist entries.
Schemas & standards
schemas/*.json, schemas/governance/*.schema.json, docs/standards/*.md
Added DET/DVP schemas, verification-summary and governance schemas, and standards docs for CSP, attestation bundle, and CAC.
Documentation & playbooks
docs/ga/*, docs/ops/*, docs/sales-toolkit/*, docs/ecosystem/*, docs/roadmap/STATUS.json, prompts/*
Large set of new governance, ops, finance, sales, and strategic documents; updated roadmap and prompts registry.
Automation & orchestration updates
scripts/configure-branch-protection.sh, scripts/pr-orchestrator-config.js, scripts/queue-performance-monitor.js, .repoos/*
Updated branch-protection and PR-orchestrator required checks, adjusted queue parallelization defaults, and increased repoos limits.
Various CI/script fixes
multiple scripts/workflows/tests
YAML merge-conflict removals, indentation fixes, added temp-file handling and improved error/output handling across CI utilities.

Sequence Diagram(s)

sequenceDiagram
    participant PR as Pull Request
    participant GH as GitHub Workflows
    participant Verifier as CI Verifiers
    participant Policy as Governance Policies
    participant K8s as Kubernetes (Kyverno/Argo)
    participant Deploy as Deployment

    PR->>GH: push / open (pull_request / merge_group)
    GH->>Verifier: run ci-guard / attestation-bundle-verifier
    Verifier->>Verifier: validate bundle (subject, sbom, provenance, policy)
    Verifier->>Policy: compare verification results to required properties
    Verifier-->>GH: emit report.json / metrics.json / stamp.json (PASS/FAIL)

    GH->>Verifier: run security-gates
    Verifier->>Verifier: check workflow pins, tools, sbom/signature rules
    Verifier-->>GH: emit security evidence (PASS/FAIL)

    GH->>Verifier: run failure-domain checks
    Verifier->>Policy: load failure-domain-map.yaml
    Verifier->>Verifier: validate domains/isolation/rollout constraints
    Verifier-->>GH: emit domain report (PASS/FAIL)

    GH->>Deploy: if all gates PASS, allow merge/deploy
    Deploy->>K8s: apply manifest
    K8s->>K8s: Kyverno validates image attestation & labels
    K8s->>K8s: Argo PreSync queries admissibility ConfigMap
    K8s-->>Deploy: admission allowed / blocked
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~65 minutes

Poem

🐰 Hop, I sniffed the evidence trail today,

Bundles, SBOMs, and signatures in play,
Gates stand tall where unsafe bits once lay,
Failure domains marked so risks won't stray,
I nudge the merge—now let good decisions stay.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/golden-main-governance-convergence-20260331

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces significant CI/CD optimizations, including a reusable workflow template, improved caching, concurrency controls, and timeout protections. It also adds documentation for enterprise deployment and compliance, along with several utility scripts for audit and security validation. My review identified several critical issues, including unresolved merge conflicts in configuration files, duplicate property declarations in TypeScript configurations, and broken absolute file paths in documentation. Additionally, several scripts contain orphaned template strings that appear to be intended as logging statements. Please resolve the merge conflicts, consolidate the duplicate types properties in tsconfig.json files, update documentation links to use relative paths, and fix the broken logging statements.

Comment on lines +1 to 7
package regulatory_early_warning

default allow = false

allow {
input.review == "approved"
input.review == "approved"
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

This file contains unresolved merge conflict markers (<<<<<<< HEAD, =======, >>>>>>>). Please resolve the conflict.

Comment on lines +8 to +17
>>>>>>> pr-21989
# GA Enforcement Lock
.github/workflows/ @BrianCLong
scripts/ci/ @BrianCLong
.ci/ @BrianCLong
>>>>>>> pr-21912
.github/workflows/ @BrianCLong
scripts/ci/ @BrianCLong
docs/ci/ @BrianCLong
>>>>>>> pr-21884
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

This file contains unresolved merge conflict markers (>>>>>>>). This will cause the CODEOWNERS file to be parsed incorrectly, potentially bypassing required reviews. Please resolve the conflicts.

Comment on lines +7 to 10
"strict": true,
"types": ["node", "jest", "uuid"],
"allowSyntheticDefaultImports": true,
"types": ["node", "jest"]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The types property is declared twice in this compilerOptions object. The second declaration on line 10 will overwrite the first one on line 8, potentially causing type resolution issues for uuid. You should merge them into a single types array.

    "types": ["node", "jest", "uuid"]

Comment on lines 3 to 12
"required_status_checks": [
"trust-chain-consistency",
"execution-graph-reconciliation"
"meta-gate",
"CI Core Gate ✅",
"Unit Tests",
"gate",
"Release Readiness Gate",
"SOC Controls",
"test (20.x)",
"Workflow Validity Check"
],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The list of required checks here seems to conflict with the changes in .github/protection-rules.yml, which simplifies the required checks to just pr-gate. Please ensure all branch protection configurations are consistent.

Comment on lines +7 to 10
"strict": true,
"types": ["node", "jest", "uuid"],
"allowSyntheticDefaultImports": true,
"types": ["node", "jest"]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The types property is declared twice. The second declaration will override the first, which includes uuid. This could lead to type errors. Please merge them into a single types array.

    "types": ["node", "jest", "uuid"]

// Get commits
const commits = getCommitsSinceTag(args.lastTag);
console.log(`Found ${commits.length} commits`);
`Found ${commits.length} commits`);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This line appears to be a leftover template string from a refactoring. It was likely intended to be a console.log statement.

  console.log(`Found ${commits.length} commits`);

Comment on lines +142 to 157
- [ ] ````yaml

```
````

- [ ] name: My Build

- [ ] on: [pull_request, push]

- [ ] jobs:
- [ ] ci:
- [ ] ci:
- [ ] uses: ./.github/workflows/ci-template-optimized.yml
- [ ] with:
- [ ] node-version: '20.x'
- [ ] cache-enabled: true
- [ ] timeout-minutes: 30
- [ ] ```

- [ ] ### **For DevOps**
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The formatting for this YAML code block is broken. The use of ```` is not standard markdown and renders incorrectly. Please use a properly indented code block within the list item.

Comment on lines +391 to +393
`Generating release notes for v${args.version}...`);
`Last tag: ${args.lastTag}`);
`Bump type: ${args.bumpType}`);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

These lines appear to be leftover template strings from a refactoring. They were likely intended to be console.log statements to provide feedback during script execution. As they are now, they have no effect.

  console.log(`Generating release notes for v${args.version}...`);
  console.log(`Last tag: ${args.lastTag}`);
  console.log(`Bump type: ${args.bumpType}`);

execCommand(`cd ${tempDir} && zip -r ${path.resolve(outputPath)} .`);

console.log(`Evidence bundle created: ${outputPath}`);
`Evidence bundle created: ${outputPath}`);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This line appears to be a leftover from a refactoring. It's a template string that isn't assigned or used. It looks like it was intended to be a console.log statement to confirm that the evidence bundle was created.

    console.log(`Evidence bundle created: ${outputPath}`);

Comment on lines +147 to +174
- [ ] ````yaml

```
````

- [ ] if: ${{ secrets.TOKEN != '' }} # Double wrapping!
- [ ] cache: npm # Without specifying cache-dependency-path
- [ ] timeout-minutes: 999 # Unrealistic timeouts
- [ ] ````

```
````

- [ ] ### ✅ Do this instead:
- [ ] ```yaml
- [ ] if: secrets.TOKEN != '' # Single evaluation
- [ ] ````yaml

```
````

- [ ] if: secrets.TOKEN != '' # Single evaluation
- [ ] cache: npm
- [ ] cache-dependency-path: '**/package-lock.json'
- [ ] timeout-minutes: 30 # Reasonable timeout
- [ ] ```

- [ ] cache-dependency-path: '\*\*/package-lock.json'
- [ ] timeout-minutes: 30 # Reasonable timeout
- [ ] ````

```
````

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The formatting for the YAML code blocks in the "Common Pitfalls to Avoid" section appears to be broken. The use of ```` is not standard for markdown code blocks and renders incorrectly. Additionally, escaping the asterisks in cache-dependency-path: '\*\*/package-lock.json' makes the YAML example invalid.

To fix this, you should use properly indented code blocks within the list items, like this:

- [ ] ### ✅ Do this instead:

      ```yaml
      if: secrets.TOKEN != '' # Single evaluation
      cache: npm
      cache-dependency-path: '**/package-lock.json'
      timeout-minutes: 30 # Reasonable timeout
      ```

Copy link
Copy Markdown
Owner Author

Superseded by #22309, which rebuilds the golden-main convergence train from a clean main base and avoids the contaminated docs-pack / mass-cleanup history on this branch. Recommended next step: review and close this PR once #22309 is the active lane.

@BrianCLong BrianCLong force-pushed the fix/golden-main-governance-convergence-20260331 branch from 3e9794d to 6c9e95e Compare March 31, 2026 18:46
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Note

Due to the large number of review comments, Critical severity comments were prioritized as inline comments.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
.github/workflows/slsa-provenance.yml (1)

20-27: ⚠️ Potential issue | 🔴 Critical

Resolve merge-conflict markers; workflow is currently invalid YAML.

Lines 20-27 still contain conflict artifacts (<<<<<<<, =======), which will break workflow parsing.

🛠️ Suggested patch
       - uses: actions/checkout@v4
-<<<<<<< HEAD
         with:
           fetch-depth: 0
           fetch-tags: true
-      - uses: pnpm/action-setup@v4
-=======
       - uses: pnpm/action-setup@v3
         with:
           version: 9.15.4
+      - uses: actions/setup-node@v4
->>>>>>> 
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/slsa-provenance.yml around lines 20 - 27, The workflow
contains Git merge conflict markers (<<<<<<<, =======, >>>>>>>) around the pnpm
action block, making the YAML invalid; remove the conflict markers and
consolidate the pnpm/action-setup step so it uses the intended version and
options (either keep pnpm/action-setup@v4 with the existing "with: fetch-depth:
0 fetch-tags: true" entries or pnpm/action-setup@v3 and move any needed "with:"
keys under that step), ensuring only a single "- uses: pnpm/action-setup@..."
line and a single "with:" mapping remain and that the fetch-depth/fetch-tags
keys are valid YAML under that step.
.github/workflows/security-gates.yml (1)

83-90: ⚠️ Potential issue | 🔴 Critical

Provenance verification step will fail on every run.

This workflow checks for out/provenance.json, out/provenance.sig, and dist/artifact.tgz at lines 83–90, but none of these files are generated within the security-gates workflow. With no job dependencies or artifact downloads, these files will never exist, causing the step to fail closed with exit code 1 on every run.

Additionally, the script path references security/verify-provenance.mjs (lowercase), but the actual file is at SECURITY/verify-provenance.mjs (case-sensitive on Linux).

Consider using a GitHub Actions conditional to skip this verification when provenance files are unavailable, or establish a clear dependency chain if this verification is mandatory:

Suggested fix
-      - name: Verify provenance (if bundle exists)
-        run: |
-          if [ -f out/provenance.json ] && [ -f out/provenance.sig ] && [ -f dist/artifact.tgz ]; then
-            node security/verify-provenance.mjs --artifact dist/artifact.tgz --provenance out/provenance.json --signature out/provenance.sig
-          else
-            echo "No local provenance bundle found; failing closed."
-            exit 1
-          fi
+      - name: Verify provenance (when bundle is present)
+        if: ${{ hashFiles('out/provenance.json', 'out/provenance.sig', 'dist/artifact.tgz') != '' }}
+        run: node SECURITY/verify-provenance.mjs --artifact dist/artifact.tgz --provenance out/provenance.json --signature out/provenance.sig
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/security-gates.yml around lines 83 - 90, The "Verify
provenance (if bundle exists)" step will always fail because
out/provenance.json, out/provenance.sig and dist/artifact.tgz are never produced
or downloaded in this workflow and the script path uses the wrong case; update
the step to either (A) make it conditional and skip when files are absent by
using a job-level conditional or an if: expression that checks for those files
before running, and correct the script path from security/verify-provenance.mjs
to the actual SECURITY/verify-provenance.mjs, or (B) add an explicit dependency
(e.g., a prior job or an artifact download) that produces/downloads
out/provenance.json, out/provenance.sig and dist/artifact.tgz before this step
and then call SECURITY/verify-provenance.mjs; ensure the step name "Verify
provenance (if bundle exists)" remains but the runtime check and script path are
fixed so the step doesn't fail closed on every run.
scripts/configure-branch-protection.sh (1)

165-178: ⚠️ Potential issue | 🟠 Major

Configuration summary contradicts the actual settings applied.

The summary output does not match the actual configuration:

  1. Line 165: States "6 required gates" but the configuration only has 4 required status checks.
  2. Line 177: States "Admin bypass available for emergencies" but enforce_admins: true (line 67) means admins are not exempt from protection rules.
  3. Line 178: States "Linear history not required" but required_linear_history: true (line 68) enforces linear history.

This mismatch could cause operational confusion when teams rely on the summary output.

Proposed fix to align the summary with actual configuration
-- **Status Checks**: 6 required gates must pass
+- **Status Checks**: 4 required gates must pass

 ## Required Status Checks:
 1. setup (environment preparation)
 2. merge-surge / merge-queue (merge-group protected-branch verification)
 3. merge-surge / pr-fast (pull-request protected-branch verification)
 4. security-gates / gate (security evidence and pinned-action enforcement)

 ## Additional Protections:
 - ✅ Dismiss stale reviews on new pushes
 - ✅ Require conversation resolution
 - ✅ Block force pushes and branch deletion
-- ⚠️  Admin bypass available for emergencies
-- 📝 Linear history not required (merge commits allowed)
+- ✅ Enforce admins (no bypass for administrators)
+- ✅ Linear history required (merge commits not allowed)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/configure-branch-protection.sh` around lines 165 - 178, Update the
human-readable summary text to reflect the actual branch protection settings
instead of hardcoded values: compute the number of required status checks from
the actual status-checks list (instead of saying "6 required gates"), derive the
admin bypass wording from the enforce_admins variable (when enforce_admins: true
say "Admin bypass NOT available"), and derive the linear-history wording from
required_linear_history (when true say "Linear history required"). Locate and
modify the summary generation logic in configure-branch-protection.sh that
prints the section containing the status checks and the three bullet lines (the
block referencing enforce_admins and required_linear_history) so it uses the
actual variables/arrays (e.g., the status checks array, enforce_admins,
required_linear_history) to build the text rather than hardcoded phrases.
🟠 Major comments (28)
scripts/check_branch_protection_convergence.mjs-24-31 (1)

24-31: ⚠️ Potential issue | 🟠 Major

Overly broad 403 handling creates a fail-open security gate.

HTTP 403 from GitHub API can indicate several conditions beyond permission denied: rate limiting (X-RateLimit-Remaining: 0), secondary rate limits, abuse detection, or IP-based blocks. Treating all 403s uniformly as "no permission" and exiting with status 0 means this governance check silently passes when it may not have actually verified anything.

For a security/governance check, consider:

  1. Inspecting the response body or X-RateLimit-* headers to distinguish permission errors from rate limits.
  2. Logging a warning but exiting non-zero (fail-closed) for ambiguous cases, or at least making the behavior configurable.
Proposed fix: distinguish permission errors from rate limits
   if (!res.ok) {
     if (res.status === 403) {
-      console.log(`No branch-protection read permission for ${path}; deferring live convergence check`);
-      process.exit(0);
+      const remaining = res.headers.get("X-RateLimit-Remaining");
+      const body = await res.text();
+      if (remaining === "0") {
+        throw new Error(`GitHub API rate limit exceeded for ${path}: ${body}`);
+      }
+      // Likely a permission issue; defer check in restricted PR contexts
+      console.log(`No branch-protection read permission for ${path}; deferring live convergence check`);
+      process.exit(0);
     }
     throw new Error(`GitHub API ${path} failed: ${res.status} ${await res.text()}`);
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/check_branch_protection_convergence.mjs` around lines 24 - 31, The
current 403 handling in the branch-protection convergence logic treats every 403
as “no permission” and exits 0; change this in the block that checks res.status
=== 403 to distinguish true permission-denied from rate-limits/abuse: read
response headers (X-RateLimit-Remaining, X-RateLimit-Reset, and any Retry-After)
and inspect the response body for rate-limit or abuse messages, and only treat
explicit permission-denied responses as the benign case (log and exit 0); for
rate-limit/abuse/ambiguous 403s log details including headers and body and exit
non-zero (fail-closed) or make this behavior configurable via an env flag, and
ensure the thrown Error for other non-ok statuses still includes res.status and
await res.text() for diagnostics.
policies/ops/verified-properties.yaml-36-42 (1)

36-42: ⚠️ Potential issue | 🟠 Major

Critical property is declared but not required in baseline.

sumit.governance.branch_protection_intact (Line 36) is marked critical but is missing from conformance.baseline_required (Line 51 onward), so baseline conformance can pass without enforcing branch-protection integrity.

Suggested fix
 conformance:
   baseline_required:
     - summit.evidence.identity_consistent
     - summit.output.deterministic
     - summit.provenance.complete
     - summit.lineage.present
+    - summit.governance.branch_protection_intact
     - summit.verification.passed

Also applies to: 50-56

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@policies/ops/verified-properties.yaml` around lines 36 - 42, The policy
declares the critical property id "summit.governance.branch_protection_intact"
but it is not listed in the conformance.baseline_required set, so baseline
checks can pass without enforcing it; update the conformance.baseline_required
array to include "summit.governance.branch_protection_intact" (ensure you use
the exact id string from the policy) and verify there are no typos (e.g.,
"sumit" vs "summit") when editing the conformance.baseline_required section to
restore enforcement.
k8s/base/kustomization.yaml-10-11 (1)

10-11: ⚠️ Potential issue | 🟠 Major

Confirm all base consumers have Kyverno/Argo assumptions satisfied.

Including these in base makes them mandatory for every consumer of this kustomization. Both dev and prod overlays inherit these resources without conditional removal. If any environment lacks Kyverno CRDs or Argo CD, apply/sync will fail.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@k8s/base/kustomization.yaml` around lines 10 - 11, The base kustomization
currently lists ../policies/kyverno-admissibility-enforcement.yaml and
../argo/admissibility-presync-check.yaml which forces every consumer to have
Kyverno and Argo; remove these two resources from the base kustomization.yaml
and instead add them only to overlays that actually require them (e.g., dev/prod
overlays), or provide an optional overlay (kyverno/argo) that consumers can
include; update overlay kustomization files to reference
kyverno-admissibility-enforcement.yaml and admissibility-presync-check.yaml so
environments missing Kyverno/Argo will not fail during apply.
scripts/queue-performance-monitor.js-381-383 (1)

381-383: ⚠️ Potential issue | 🟠 Major

Update job IDs to use full check contexts matching downstream governance requirements.

The bare job IDs (attestation-bundle-verifier, pr-fast, gate) in the enableParallelization() method do not match the full check contexts expected by downstream consumers. The governance config at governance/ga/required-checks.yaml and branch protection setup require full workflow/job context format: ci-guard / attestation-bundle-verifier, merge-surge / pr-fast, security-gates / gate. This mapping will misalign if this code is integrated with consumers expecting full contexts.

Mismatched contexts

In queue-performance-monitor.js (lines 381-383):

'jobs-can-run-in-parallel': [
  'attestation-bundle-verifier',
  'pr-fast',
  'gate',
],

Expected format in governance/ga/required-checks.yaml:

required_checks:
  - ci-guard / attestation-bundle-verifier
  - merge-surge / merge-queue
  - merge-surge / pr-fast
  - security-gates / gate
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/queue-performance-monitor.js` around lines 381 - 383, The
jobs-can-run-in-parallel list in enableParallelization() uses bare job IDs;
update those entries in queue-performance-monitor.js to use the full check
context strings expected by downstream governance: replace
'attestation-bundle-verifier' with 'ci-guard / attestation-bundle-verifier',
'pr-fast' with 'merge-surge / pr-fast', and 'gate' with 'security-gates / gate'
so the array matches the required-checks format.
k8s/policies/kyverno-admissibility-enforcement.yaml-40-43 (1)

40-43: ⚠️ Potential issue | 🟠 Major

Replace subject with subjectRegExp for proper keyless identity matching in Kyverno.

In Kyverno verifyImages keyless attestors, the subject field does not support wildcard patterns. Use subjectRegExp instead for pattern matching. The current subject: https://github.com/*/* is both syntactically incorrect for Kyverno and overly permissive—it allows any GitHub repository to pass verification.

Replace with subjectRegExp and restrict the pattern to your organization and specific workflows. For example:

Proposed fix
               entries:
                 - keyless:
                     issuer: https://token.actions.githubusercontent.com
-                    subject: https://github.com/*/*
+                    subjectRegExp: "^https://github\\.com/BrianCLong/summit/\\.github/workflows/.+@refs/heads/main$"

The GitHub Actions OIDC certificate identity format is https://github.com/<OWNER>/<REPO>/.github/workflows/<WORKFLOW>@refs/heads/<BRANCH>, so use a regex pattern that enforces your repository and workflow boundaries.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@k8s/policies/kyverno-admissibility-enforcement.yaml` around lines 40 - 43,
The Kyverno verifyImages keyless attestor currently uses the
unsupported/wildcard-prone field subject with value https://github.com/*/*;
change this to subjectRegExp and provide a restrictive regex that matches your
GitHub org/repo/workflow identity (use the GitHub Actions OIDC format
https://github.com/<OWNER>/<REPO>/.github/workflows/<WORKFLOW>@refs/heads/<BRANCH>),
i.e., replace the subject key under the keyless attestor with subjectRegExp and
tighten the regex to your organization and workflow names so only intended
repositories/workflows can match while leaving issuer and keyless block intact.
policy/actions-allowlist.json-18-23 (1)

18-23: ⚠️ Potential issue | 🟠 Major

Coverage gap must be resolved before merging: 106 workflows using these actions are not in workflow_files.

The allowlist is being expanded without coverage verification. The initial shell output shows 106 workflows using the newly allowlisted actions but excluded from policy.workflow_files. Additionally, 76+ non-SHA references exist (e.g., @v4, @v6, @v2) across workflows where immutable pinning appears required. Either add all 106 workflows to workflow_files, remove the allowlist entries, or explicitly document why some workflows remain uncovered by policy.

Examples of uncovered workflows and non-SHA references

Uncovered workflows (sample):

  • .github/workflows/_golden-path-pipeline.yml
  • .github/workflows/_reusable-build.yml
  • .github/workflows/api-determinism-check.yml
  • .github/workflows/ci-security.yml
  • .github/workflows/lex-governance.yml
  • (99 more)

Non-SHA references (sample):

  • .github/workflows/docs-fast-track.yml:163: uses: actions/github-script@v6
  • .github/workflows/go-live-gate.yml:91: uses: actions/cache@v4
  • .github/workflows/compliance-sbom-gate.yml:73: uses: gitleaks/gitleaks-action@v2
  • .github/workflows/lex-governance.yml:75-346: uses: actions/download-artifact@v4 (11 instances)
  • (60+ more)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@policy/actions-allowlist.json` around lines 18 - 23, The allowlist entries
for actions/cache, actions/create-github-app-token, actions/download-artifact,
actions/github-script, actions/upload-artifact, and gitleaks/gitleaks-action
were added without covering 106 workflows and leave 76+ non-SHA uses; fix by
either (A) adding all uncovered workflow filenames to policy.workflow_files so
these workflows are covered by the new allowlist, or (B) remove the listed
entries from policy/actions-allowlist.json and instead create explicit
per-workflow exceptions with rationale, and in either case update all non-SHA
references (e.g., uses: actions/github-script@v6, actions/cache@v4,
gitleaks/gitleaks-action@v2, actions/download-artifact@v4) to immutable
SHA-pinned versions in the referenced workflows (or document and approve any
documented exceptions) so policy coverage and immutable pinning requirements are
satisfied.
k8s/server-deployment.yaml-13-13 (1)

13-13: ⚠️ Potential issue | 🟠 Major

Remove the self-asserted admissibility label from the workload manifest.

The workload claims security.summit.io/admissibility: "PASS" directly in its manifest, but this label should only be added by the policy after verifying evidence. Configure the Kyverno policy to mutate this label only after successful image verification and attestation checks. This eliminates self-assertion and ensures the label represents verified compliance, not a workload claim.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@k8s/server-deployment.yaml` at line 13, Remove the self-asserted label key
security.summit.io/admissibility: "PASS" from the workload manifest
(server-deployment.yaml) and instead configure your Kyverno mutate rule to add
or update the security.summit.io/admissibility label only after the image
verification and attestation checks succeed; locate the Kyverno policy rule that
performs image verification/attestation and add a mutate/block action that sets
security.summit.io/admissibility="PASS" on the Pod/Deployment only when those
verification conditions are met so the label is policy-applied rather than
self-declared.
governance/ga/required-checks.yaml-2-3 (1)

2-3: ⚠️ Potential issue | 🟠 Major

Governance gap confirmed: release/* scope dropped from required-checks policy.

Release branches (release/v*, release/*-stabilization, etc.) are actively used per operational runbooks and CI/CD workflows, but governance/ga/required-checks.yaml now protects only main. This scope reduction weakens required-check enforcement on release lanes, allowing merges to release branches to bypass the checks defined in lines 5–10 (attestation-bundle-verifier, merge-queue, pr-fast, security-gates).

Restore release/* pattern to protected_branches to maintain governance parity with release operations.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@governance/ga/required-checks.yaml` around lines 2 - 3, The
protected_branches list currently only includes "main" which removes
required-check enforcement for release lanes; update the protected_branches
entry to include the release patterns (for example "release/*", optionally
"release/v*" and "release/*-stabilization") so that the checks referenced
(attestation-bundle-verifier, merge-queue, pr-fast, security-gates) continue to
apply to release branches; modify the protected_branches array (symbol:
protected_branches) to add the appropriate release/* patterns and commit the
change.
schemas/det.schema.json-25-28 (1)

25-28: ⚠️ Potential issue | 🟠 Major

Root DET records are currently impossible to represent.

parent_run_id is required with minLength: 1, so a top-level run cannot validate without a synthetic parent. Allow null (or make it optional) for root traces to avoid invalidating legitimate root executions.

Proposed schema adjustment
   "parent_run_id": {
-    "type": "string",
-    "minLength": 1
+    "type": ["string", "null"],
+    "minLength": 1
   },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@schemas/det.schema.json` around lines 25 - 28, The schema currently mandates
parent_run_id as a non-empty string, preventing root DET records; change the
parent_run_id definition so it can be null or omitted for root traces — e.g.,
make parent_run_id optional or set its type to allow null (type:
["string","null"]) while keeping minLength: 1 for the string branch (or use
oneOf/anyOf with a string schema and a null schema) so existing non-empty parent
IDs still validate. Ensure you update the parent_run_id property in the schema
(and any required list that includes it) to reflect this change.
schemas/det.schema.json-53-84 (1)

53-84: ⚠️ Potential issue | 🟠 Major

Required arrays should enforce non-empty evidence/verdict payloads.

evidence_ids and policy_verdicts are required but can be [], which weakens the contract. Add minItems: 1 to prevent empty “valid” traces.

Proposed schema hardening
     "evidence_ids": {
       "type": "array",
+      "minItems": 1,
       "items": {
         "type": "string",
         "minLength": 1
       }
     },
     "policy_verdicts": {
       "type": "array",
+      "minItems": 1,
       "items": {
         "type": "object",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@schemas/det.schema.json` around lines 53 - 84, The arrays "evidence_ids" and
"policy_verdicts" currently allow empty arrays; add "minItems": 1 to each array
definition so they cannot be [] (i.e., update the "evidence_ids" object and the
"policy_verdicts" object to include "minItems": 1). Keep the existing item
constraints for "evidence_ids" (string, minLength:1) and for "policy_verdicts"
(object with required ["policy","status"] and additionalProperties:false)
unchanged so each array must contain at least one valid element.
scripts/ci/check_failure_isolation.mjs-10-26 (1)

10-26: ⚠️ Potential issue | 🟠 Major

Security: Use YAML.safe_load_file instead of YAML.load_file.

Same issue as in verify_failure_semantics.mjs. The YAML.load_file method can deserialize arbitrary Ruby objects, which is a security risk.

🔒 Proposed fix
 function readYaml(filePath) {
   const result = spawnSync(
     'ruby',
     [
       '-e',
-      'require "yaml"; require "json"; puts JSON.generate(YAML.load_file(ARGV[0]))',
+      'require "yaml"; require "json"; puts JSON.generate(YAML.safe_load_file(ARGV[0], permitted_classes: [], permitted_symbols: [], aliases: true))',
       filePath
     ],
     { encoding: 'utf8' }
   );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/ci/check_failure_isolation.mjs` around lines 10 - 26, The readYaml
function uses a Ruby one-liner that calls YAML.load_file which can deserialize
arbitrary Ruby objects; update the inline Ruby snippet in readYaml to call
YAML.safe_load_file(ARGV[0]) instead of YAML.load_file(ARGV[0]) so the YAML is
parsed with safe loading semantics (adjust any permitted classes/aliases if
needed for expected content).
scripts/ci/verify_failure_semantics.mjs-16-32 (1)

16-32: ⚠️ Potential issue | 🟠 Major

Security: Use YAML.safe_load_file instead of YAML.load_file.

YAML.load_file in Ruby can deserialize arbitrary Ruby objects (via !!ruby/object tags), which is a code execution vulnerability if the YAML file could be attacker-controlled. While the policy file is likely trusted, using safe_load_file is a defense-in-depth practice.

Additionally, consider using a JavaScript YAML parser (e.g., js-yaml) instead of shelling out to Ruby, reducing the dependency footprint and potential attack surface.

🔒 Proposed fix for YAML parsing
 function readYaml(filePath) {
   const result = spawnSync(
     'ruby',
     [
       '-e',
-      'require "yaml"; require "json"; puts JSON.generate(YAML.load_file(ARGV[0]))',
+      'require "yaml"; require "json"; puts JSON.generate(YAML.safe_load_file(ARGV[0], permitted_classes: [], permitted_symbols: [], aliases: true))',
       filePath
     ],
     { encoding: 'utf8' }
   );

Or better, use a JS YAML library:

import yaml from 'js-yaml';

function readYaml(filePath) {
  return yaml.load(fs.readFileSync(filePath, 'utf8'));
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/ci/verify_failure_semantics.mjs` around lines 16 - 32, The readYaml
function currently shells out via spawnSync running Ruby and calls
YAML.load_file which can deserialize arbitrary Ruby objects; change the Ruby
invocation in readYaml to use YAML.safe_load_file(ARGV[0]) instead of
YAML.load_file(ARGV[0]) so the spawned process only uses safe_load behavior,
update the error handling to surface any stderr from spawnSync as before, or
better yet replace the entire spawnSync approach with a JS YAML parser (e.g.,
use js-yaml + fs.readFileSync) inside readYaml to avoid shelling out; refer to
function name readYaml and the spawnSync invocation when making the change.
schemas/governance/verification-summary.schema.json-106-113 (1)

106-113: ⚠️ Potential issue | 🟠 Major

Make result and failure_class self-consistent.

This schema currently accepts contradictory summaries like {"result":"PASS","failure_class":"POLICY"} and {"result":"FAIL","failure_class":"NONE"}. That weakens downstream gates because different consumers can reach different conclusions from the same document.

Example guard
"allOf": [
  {
    "if": {
      "properties": { "result": { "const": "PASS" } },
      "required": ["result"]
    },
    "then": {
      "properties": { "failure_class": { "const": "NONE" } }
    }
  },
  {
    "if": {
      "properties": {
        "result": { "enum": ["FAIL", "REVIEW_REQUIRED"] }
      },
      "required": ["result"]
    },
    "then": {
      "properties": {
        "failure_class": {
          "enum": [
            "STRUCT",
            "ACQ",
            "CRYPTO",
            "IDENTITY",
            "SEMANTIC",
            "POLICY",
            "DRIFT"
          ]
        }
      }
    }
  }
]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@schemas/governance/verification-summary.schema.json` around lines 106 - 113,
The schema allows contradictory combinations between the "result" and
"failure_class" fields; add an "allOf" conditional guard to enforce consistency:
when "result" is "PASS" require "failure_class" to be "NONE", and when "result"
is "FAIL" or "REVIEW_REQUIRED" require "failure_class" to be one of
["STRUCT","ACQ","CRYPTO","IDENTITY","SEMANTIC","POLICY","DRIFT"]; update the
schema surrounding the "result" and "failure_class" definitions to include these
"if"/"then" clauses so downstream consumers cannot see mismatched summaries.
scripts/ci/verify_required_checks_contract.mjs-20-39 (1)

20-39: ⚠️ Potential issue | 🟠 Major

Replace Python-based YAML parsing with native JavaScript alternative.

The loadYaml() function introduces an undeclared runtime dependency on python3 and PyYAML without explicit setup in the CI context. While js-yaml is already available in the project (in packages/summit-governance/), shelling out to Python creates a fragile fallback path that could fail before contract checks run.

Use js-yaml instead to keep the verifier self-contained and deterministic.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/ci/verify_required_checks_contract.mjs` around lines 20 - 39, The
loadYaml function currently shells out to python3 via spawnSync (referenced as
spawnSync and loadYaml) which creates an undeclared runtime dependency; replace
that logic with the project's js-yaml parser: require or import 'js-yaml' (e.g.,
const { load } = require('js-yaml') or import { load } from 'js-yaml'), read the
file with fs.readFileSync as you already do, then parse the string with load
inside a try/catch and on error throw a descriptive Error(`Failed to parse YAML
${file}: ${err.message}`); remove the spawnSync usage and any references to
python/PyYAML so loadYaml returns the parsed object directly from js-yaml.
scripts/ci/check_failure_domains.mjs-125-127 (1)

125-127: ⚠️ Potential issue | 🟠 Major

The schema file is parsed, but never enforced.

readJson(schemaPath) only proves that failure-domain.schema.json is valid JSON. None of its constraints participate in validation, so the schema can drift away from validateDomain() while the report still advertises schema_path as part of the contract.

Also applies to: 171-174

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/ci/check_failure_domains.mjs` around lines 125 - 127, The schema file
is being parsed with readJson(schemaPath) but never used to validate domains;
update main() (and the similar block at lines ~171-174) to compile and apply the
JSON Schema when validating each domain: load the schema from schemaPath into a
validator (e.g., Ajv or the project's existing validateDomain helper), replace
any superficial read-only checks with calls to that compiled validator, and
ensure validateDomain() or the report generation calls the validator and
fails/reports schema validation errors for non-conforming domain objects so the
advertised schema_path is actually enforced.
docs/ga/FAILURE_CONTAINMENT_DOCTRINE.md-21-27 (1)

21-27: ⚠️ Potential issue | 🟠 Major

Make cross-domain exceptions part of the evidence contract.

The doctrine says cross-domain propagation is only valid with an approved exception, but the minimum evidence set never records that exception or allowance. Without that reference, a gate cannot distinguish approved propagation from policy drift deterministically.

Also applies to: 67-72

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/ga/FAILURE_CONTAINMENT_DOCTRINE.md` around lines 21 - 27, The policy
text requires that cross-domain propagation be allowed only with an approved
exception, but the minimum evidence contract never records that exception;
update the evidence contract and any references to the “minimum evidence set”
(the data used to evaluate items 1–5 and the "containment verdict") to include
an explicit cross-domain-exception field (e.g., approvedExceptionId /
exceptionReference and exceptionTimestamp) and ensure rule 5 (cross-domain
propagation) must check that field when deciding validity so gates can
deterministically distinguish approved propagation from policy drift.
docs/ops/summit-customer-proof-and-evidence-standards.md-68-72 (1)

68-72: ⚠️ Potential issue | 🟠 Major

Define publication controls for the partner audience.

partner is an allowed audience and appears in Level 4 examples, but the publication rules only cover internal, customer-facing, board, and public use. That leaves approval and redaction expectations for partner collateral undefined even though it is an external distribution channel.

Also applies to: 141-147, 230-236, 323-345

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/ops/summit-customer-proof-and-evidence-standards.md` around lines 68 -
72, Update the "Level 4: Publishable" section to explicitly define publication
controls for the partner audience: under the Level 4 bullets (the "Level 4:
Publishable" heading and its examples) add a clear rule that partner-facing
collateral requires (a) documented partner approval authority (e.g., Partner PM
or Legal), (b) a redaction checklist and release record entry similar to public
materials, and (c) allowed uses and distribution channels for partner materials
(e.g., co-branded one-pager, partner portal) including any exceptions; apply the
same explicit partner-audience wording to the other Level 4 occurrences
referenced so all "partner" examples have consistent approval, redaction, and
release-record requirements.
docs/standards/cognitive-security-protocol-v0.1.md-137-145 (1)

137-145: ⚠️ Potential issue | 🟠 Major

The minimum portable set contradicts the baseline admissibility contract.

Baseline admissibility requires summit.provenance.complete and summit.lineage.present, but the minimum CSP portability check only requires subject.json, verification-summary.json, decision-proof.json, and policy.json. As written, a bundle can omit provenance.json or lineage.json and still look portable under CSP. Either require those files here or explicitly call this command a preflight coherence check rather than the baseline admissibility verifier.

Also applies to: 201-216

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/standards/cognitive-security-protocol-v0.1.md` around lines 137 - 145,
The minimum CSP portability check contradicts the baseline admissibility
contract because baseline requires summit.provenance.complete and
summit.lineage.present but the portability list only mandates subject.json,
verification-summary.json, decision-proof.json, and policy.json; update the
portability requirements to also require provenance.json and lineage.json (or
the metadata that maps to summit.provenance.complete and summit.lineage.present)
so bundles that pass portability also satisfy baseline admissibility, or
alternatively rename/label this command and documentation as a "preflight
coherence check" (not the baseline admissibility verifier) and add an explicit
note referencing summit.provenance.complete and summit.lineage.present to avoid
confusion.
.github/workflows/failure-isolation.yml-4-10 (1)

4-10: ⚠️ Potential issue | 🟠 Major

Include this workflow in its own paths filter.

A PR can modify .github/workflows/failure-isolation.yml without running this gate because the workflow file itself is not matched by the paths filter. This creates a blind spot where workflow logic changes won't be tested against the current failure domain configuration. Include the workflow file to ensure changes to the control surface are automatically validated.

🔍 Minimal fix
   pull_request:
     branches:
       - main
       - release/*
     paths:
+      - '.github/workflows/failure-isolation.yml'
       - 'policies/ops/failure-domain-map.yaml'
       - 'scripts/ci/check_failure_isolation.mjs'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/failure-isolation.yml around lines 4 - 10, Update the
workflow's paths filter so the workflow file itself is included: modify the
'paths' array in the pull_request trigger for the workflow (the paths list that
currently contains 'policies/ops/failure-domain-map.yaml' and
'scripts/ci/check_failure_isolation.mjs') to also include
'.github/workflows/failure-isolation.yml' so changes to the workflow file
trigger the job; ensure the entry matches the existing quoting/format style used
in the paths list.
scripts/ci/verify_security_gate.mjs-292-305 (1)

292-305: ⚠️ Potential issue | 🟠 Major

stamp.json is not deterministic.

Line 301 bakes wall-clock time into the evidence. Identical workflow and policy inputs will still produce different stamp.json bytes and hashes, which undercuts the deterministic-gate contract.

🔧 Use a reproducible timestamp or omit it
-        timestamp: new Date().toISOString()
+        timestamp: process.env.SOURCE_DATE_EPOCH
+          ? new Date(Number(process.env.SOURCE_DATE_EPOCH) * 1000).toISOString()
+          : null
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/ci/verify_security_gate.mjs` around lines 292 - 305, The stamp.json
output currently embeds a non-deterministic wall-clock timestamp via new
Date().toISOString() inside the writeFileSync call that creates stamp.json,
making sha256(stamp.json) non-reproducible; change the code that builds the JSON
object (the block feeding JSON.stringify in writeFileSync) to use a
deterministic timestamp source (for example derive timestamp from report data or
metricsHash, use a fixed reproducible value, or omit the timestamp field
entirely) instead of new Date().toISOString() so identical inputs produce
identical stamp.json bytes and hashes.
.github/workflows/admissibility-gate.yml-36-39 (1)

36-39: ⚠️ Potential issue | 🟠 Major

Bind the attestation subject to the actual governed inputs.

Line 39 hashes only package.json and pnpm-lock.yaml. A PR that changes workflows, policies, or verifier scripts without touching those two files gets the same subject digest, so the evidence is not actually attached to the change under review.

🔧 One way to make the subject meaningful
       - name: Build deterministic artifact payload
         run: |
-          mkdir -p dist
-          sha256sum package.json pnpm-lock.yaml | awk '{print $1}' | sort > dist/admissible-artifact.txt
+          mkdir -p dist evidence
+          git ls-files -z \
+            | sort -z \
+            | xargs -0 sha256sum > dist/admissible-artifact.manifest
+          sha256sum dist/admissible-artifact.manifest | awk '{print $1}' > dist/admissible-artifact.txt
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/admissibility-gate.yml around lines 36 - 39, The current
"Build deterministic artifact payload" step only hashes package.json and
pnpm-lock.yaml, so attestation subjects won't change when workflows, policies,
or verifier scripts change; update the run command that produces
dist/admissible-artifact.txt (the sha256sum pipeline) to include all governed
inputs — e.g., use git ls-files to list tracked files and filter to include
package.json, pnpm-lock.yaml plus .github/workflows/**, any policies directory,
and verifier scripts (or simply hash all tracked files) then sort and write
their checksums so the attestation subject is actually bound to those inputs.
.github/workflows/admissibility-gate.yml-16-17 (1)

16-17: ⚠️ Potential issue | 🟠 Major

Pin every external action to an immutable commit SHA.

All six external actions in this workflow use mutable version tags (v4, v3, v0.17.0) instead of commit SHAs. In a required governance gate, this allows upstream retagging to alter behavior without any repository diff to review.

  • Line 17: actions/checkout@v4
  • Line 20: actions/setup-node@v4
  • Line 31: anchore/sbom-action/download-syft@v0.17.0
  • Line 34: sigstore/cosign-installer@v3.8.1
  • Line 50: actions/attest-build-provenance@v3
  • Line 86: actions/upload-artifact@v4

Replace each with the corresponding commit SHA.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/admissibility-gate.yml around lines 16 - 17, Replace each
mutable action version tag with its corresponding immutable commit SHA: update
occurrences of actions/checkout@v4, actions/setup-node@v4,
anchore/sbom-action/download-syft@v0.17.0, sigstore/cosign-installer@v3.8.1,
actions/attest-build-provenance@v3, and actions/upload-artifact@v4 to the exact
commit SHAs (retrieved from the respective GitHub action repositories) so the
workflow pins to immutable commits instead of floating tags; ensure you replace
the tag strings in the workflow file where those action identifiers appear and
verify the SHA values by checking the action repo tags/releases before
committing.
.github/workflows/admissibility-gate.yml-68-72 (1)

68-72: ⚠️ Potential issue | 🟠 Major

Use keyless/OIDC signing or a pre-trusted key, not per-run local key generation.

The self-signed approach in this workflow does not establish authenticity. Generating a fresh key pair and verifying with the matching public key from the same run proves only round-tripping, not trust.

Sigstore/Cosign recommends:

  • Keyless (OIDC) signing (preferred for CI): Cosign generates an ephemeral key bound to the CI workflow identity via Fulcio, records to Rekor, and verification checks the certificate's expected identity and OIDC issuer rather than trusting a just-generated public key.
  • Pre-trusted keys: Use a stable key stored in KMS/HSM/secret management, verified with a pre-distributed or KMS-referenced public key.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/admissibility-gate.yml around lines 68 - 72, Replace the
per-run generated key flow (remove cosign generate-key-pair and the
sign-blob/verify-blob pair) with either keyless OIDC signing (use cosign sign
--keyless and cosign verify --keyless, ensuring the CI has OIDC configured) or a
pre-trusted KMS/secret-managed key (call cosign sign --key <KMS-or-secret-ref>
and verify with the corresponding trusted public key or KMS-backed
verification), and update the signing/verification commands that currently
reference evidence/artifact.sig and dist/admissible-artifact.txt accordingly.
scripts/ci/verify_security_gate.mjs-46-63 (1)

46-63: ⚠️ Potential issue | 🟠 Major

Replace Python YAML parsing with js-yaml to eliminate undeclared runtime dependency.

The parseYaml function shells out to python3 -c "import yaml" (line 50), creating a hard dependency on PyYAML. However, the workflow .github/workflows/security-gates.yml that executes this verifier does not install PyYAML. Since js-yaml is already in package.json, use it directly instead of depending on external Python provisioning.

🔧 Use js-yaml instead of Python
-import { spawnSync } from 'node:child_process';
+import yaml from 'js-yaml';
+import { readFileSync } from 'node:fs';
 
 function parseYaml(filePath) {
-  const loader = [
-    'import json',
-    'import sys',
-    'import yaml',
-    'from yaml import BaseLoader',
-    'with open(sys.argv[1], "r", encoding="utf-8") as fh:',
-    '    data = yaml.load(fh, Loader=BaseLoader)',
-    'json.dump(data, sys.stdout)'
-  ].join('\n');
-  const result = spawnSync('python3', ['-c', loader, filePath], {
-    encoding: 'utf8'
-  });
-  if (result.status !== 0) {
-    throw new Error(result.stderr.trim() || `Failed to parse YAML: ${filePath}`);
-  }
-  return JSON.parse(result.stdout);
+  return yaml.load(readFileSync(filePath, 'utf8'), {
+    schema: yaml.FAILSAFE_SCHEMA,
+  });
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/ci/verify_security_gate.mjs` around lines 46 - 63, The parseYaml
function currently shells out via the loader and spawnSync to call Python/PyYAML
(see loader and spawnSync usage); replace it with direct JS parsing using
js-yaml: read the file with fs.readFileSync(filePath, 'utf8') and parse with
require('js-yaml').load (or safeLoad depending on version) to return the JS
object, and on parse or read errors throw a clear Error including the filePath;
remove the loader variable and spawnSync call and ensure the function still
returns the parsed JSON-compatible object.
docs/standards/CAC_v1.0.md-61-62 (1)

61-62: ⚠️ Potential issue | 🟠 Major

Hash algorithm policy conflicts with schema constraints.

Line 61 permits “SHA-256 or stronger”, but the schemas hardcode SHA-256-only fields/patterns. This makes stronger hashes non-conformant even though the normative text allows them.

Proposed fix (tighten policy to current schema behavior)
-2. Be assigned a content hash (SHA-256 or stronger).
+2. Be assigned a SHA-256 content hash.

Also applies to: 167-178, 187-198, 303-304, 356-356

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/standards/CAC_v1.0.md` around lines 61 - 62, The policy text allows
“SHA-256 or stronger” but the schema enforces SHA-256 only; update the normative
text to match the schema by replacing occurrences of “SHA-256 or stronger” (and
similar phrasing) with “SHA-256” in the bullets and sections referenced (e.g.,
the line containing “Be assigned a content hash (SHA-256 or stronger)” and the
other occurrences at the ranges noted: 167-178, 187-198, 303-304, 356). Ensure
all instances of the phrase and any related statements that imply support for
stronger digests are tightened to explicitly require SHA-256 so the document and
schemas remain consistent.
docs/standards/CAC_v1.0.md-144-145 (1)

144-145: ⚠️ Potential issue | 🟠 Major

MINOR versioning rule is incompatible with strict unknown-field rejection.

Line 144 enforces additionalProperties: false, so adding schema fields will break older validators. Line 403 currently labels additive schema fields as MINOR, which is not backward-compatible under this rule.

Proposed fix (align versioning semantics)
-- `MINOR`: additive compatible controls or schema fields.
+- `MINOR`: additive compatible controls that do not require new schema fields.
+- `MAJOR`: any schema field additions/removals/renames when `additionalProperties: false` is enforced.

Also applies to: 402-404

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/standards/CAC_v1.0.md` around lines 144 - 145, The doc currently
mandates strict unknown-field rejection via "additionalProperties: false" while
separately treating additive schema changes as MINOR, which breaks older
validators; update the standard so that either the "additionalProperties: false"
requirement is removed/relaxed (e.g., require additionalProperties: true or
allow unknown fields) or change the versioning rule for additive schema fields
(the "MINOR" designation referenced around lines 402-404) to require MAJOR
changes; specifically, reconcile the rule by (a) replacing the "MUST reject
unknown fields (`additionalProperties: false`)" language with a statement that
unknown fields are permitted for forward-compatibility (and keep enforcement of
required properties), or (b) change the wording that labels additive schema
fields as MINOR to require MAJOR — update the sentences that mention
"additionalProperties: false" and the "MINOR" labeling so their semantics are
consistent.
lib/admissibility.ts-82-95 (1)

82-95: ⚠️ Potential issue | 🟠 Major

Artifact digest is not validated before PASS is possible.

Line 92 forwards artifact.digest without validity checks. A malformed digest can still result in PASS.

Proposed fix (enforce digest integrity in gate result)
 export interface AdmissibilityVerdict {
@@
   checks: {
+    artifactDigestValid: boolean;
     signatureValid: boolean;
     sbomComplete: boolean;
     provenanceIntact: boolean;
     prohibitedDependencies: boolean;
   };
@@
   const reasons: string[] = [];
+  const artifactDigestValid = /^[a-f0-9]{64}$/.test(evidenceBundle.artifact.digest);
+  if (!artifactDigestValid) {
+    reasons.push("INVALID_ARTIFACT_DIGEST");
+  }
@@
     checks: {
+      artifactDigestValid,
       signatureValid,
       sbomComplete,
       provenanceIntact,
       prohibitedDependencies,
     },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/admissibility.ts` around lines 82 - 95, The return currently forwards
evidenceBundle.artifact.digest without validating it, allowing a PASS despite a
malformed digest; update the logic in lib/admissibility.ts (the function that
builds the gate result returning status, reasons, checks, artifact) to validate
evidenceBundle.artifact.digest (e.g., match expected hash format/algorithm) and
add a new check flag (artifactDigestValid) into the checks object, append a
descriptive reason when the digest is invalid, and ensure the final status is
computed using reasons.length === 0 AND artifactDigestValid so PASS cannot occur
if the digest fails validation.
lib/admissibility.ts-76-80 (1)

76-80: ⚠️ Potential issue | 🟠 Major

Reason code payload format breaks contract compatibility.

Line 79 embeds dependency names into the reason code (PROHIBITED_DEPENDENCIES:<...>). That is not a stable reason code shape and will not match strict uppercase code contracts.

Proposed fix (stable reason code + structured details)
 export interface AdmissibilityVerdict {
   status: AdmissibilityStatus;
   reasons: string[];
+  reasonDetails?: {
+    prohibitedDependencies?: string[];
+  };
   checks: {
     signatureValid: boolean;
     sbomComplete: boolean;
     provenanceIntact: boolean;
     prohibitedDependencies: boolean;
@@
-  if (!prohibitedDependencies) {
-    const blocked = sortUnique(evidenceBundle.dependencies.prohibitedFound).join(",");
-    reasons.push(`PROHIBITED_DEPENDENCIES:${blocked}`);
-  }
+  const blocked = sortUnique(evidenceBundle.dependencies.prohibitedFound);
+  if (!prohibitedDependencies) {
+    reasons.push("PROHIBITED_DEPENDENCIES_FOUND");
+  }
@@
     reasons,
+    reasonDetails: blocked.length ? { prohibitedDependencies: blocked } : undefined,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/admissibility.ts` around lines 76 - 80, The current logic appends
dependency names into the reason code
(reasons.push(`PROHIBITED_DEPENDENCIES:${blocked}`)), which breaks the stable
uppercase reason contract; instead push a stable reason code (e.g.,
reasons.push('PROHIBITED_DEPENDENCIES')) and record the actual blocked
dependency list as structured details separately (for example add or populate a
reasonsDetails map/object keyed by 'PROHIBITED_DEPENDENCIES' or append a {code:
'PROHIBITED_DEPENDENCIES', details: {blocked:
sortUnique(evidenceBundle.dependencies.prohibitedFound)}} entry), using the
existing evidenceBundle.dependencies.prohibitedFound and sortUnique to provide
an array of names (do not embed them in the reason string).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a849e810-a1f4-4fbf-b4e5-fd7b21f14a5b

📥 Commits

Reviewing files that changed from the base of the PR and between 12cad4a and b19e8eb.

📒 Files selected for processing (117)
  • .github/merge-queue-config.json
  • .github/required-checks.yml
  • .github/scripts/run-agent-graph-check.ts
  • .github/workflows/_policy-enforcer.yml
  • .github/workflows/admissibility-gate.yml
  • .github/workflows/branch-protection-drift.yml
  • .github/workflows/ci-guard.yml
  • .github/workflows/ci.yml
  • .github/workflows/cosign-verify.yml
  • .github/workflows/failure-domain-declaration.yml
  • .github/workflows/failure-isolation.yml
  • .github/workflows/failure-semantics.yml
  • .github/workflows/ga-gate.yml
  • .github/workflows/merge-queue.yml
  • .github/workflows/release-train.yml
  • .github/workflows/security-gates.yml
  • .github/workflows/slsa-provenance.yml
  • .github/workflows/soc-controls.yml
  • .github/workflows/telemetry-lineage-gates.yml
  • .github/workflows/unit-test-coverage.yml
  • .github/workflows/workflow-lint.yml
  • charts/companyos/templates/admissibility-presync-job.yaml
  • deploy/helm/summit/templates/admissibility-presync-job.yaml
  • docs/DECISION_EXECUTION_TRACE.md
  • docs/DECISION_VALIDITY_PROTOCOL.md
  • docs/ecosystem/summit-partner-operations-appendix.md
  • docs/ecosystem/summit-partner-operations.md
  • docs/ga/FAILURE_CONTAINMENT_ARCHITECTURE.md
  • docs/ga/FAILURE_CONTAINMENT_DOCTRINE.md
  • docs/governance/REQUIRED_CHECKS_CONTRACT.yml
  • docs/ops/summit-annual-planning-workbook.md
  • docs/ops/summit-board-and-investor-update-templates.md
  • docs/ops/summit-board-appendices.md
  • docs/ops/summit-board-operating-pack.md
  • docs/ops/summit-cognitive-operating-system.md
  • docs/ops/summit-cognitive-strategic-advantage-playbook.md
  • docs/ops/summit-company-okr-system.md
  • docs/ops/summit-company-operating-manual.md
  • docs/ops/summit-company-operating-rhythm.md
  • docs/ops/summit-company-scorecard.md
  • docs/ops/summit-customer-proof-and-evidence-standards.md
  • docs/ops/summit-decision-log-and-exception-template.md
  • docs/ops/summit-department-operating-charters.md
  • docs/ops/summit-evidence-standards-appendix.md
  • docs/ops/summit-finance-runway-operating-pack.md
  • docs/ops/summit-finance-workbook-spec.md
  • docs/ops/summit-founder-playbook.md
  • docs/ops/summit-fundraising-and-data-room.md
  • docs/ops/summit-fundraising-process-appendix.md
  • docs/ops/summit-internal-academy-and-onboarding.md
  • docs/ops/summit-internal-communications-and-escalation-playbook.md
  • docs/ops/summit-kpi-to-decision-map.md
  • docs/ops/summit-manager-and-hiring-scorecards.md
  • docs/ops/summit-meeting-and-ritual-templates.md
  • docs/ops/summit-product-and-gtm-interface-charter.md
  • docs/ops/summit-scenario-planning-playbook.md
  • docs/roadmap/STATUS.json
  • docs/sales-toolkit/summit-customer-lifecycle-playbook.md
  • docs/sales-toolkit/summit-customer-success-playbook.md
  • docs/sales-toolkit/summit-enterprise-procurement-appendix.md
  • docs/sales-toolkit/summit-enterprise-procurement-playbook.md
  • docs/sales-toolkit/summit-qbr-and-ebr-pack.md
  • docs/sales-toolkit/summit-renewal-and-expansion-playbook.md
  • docs/sales-toolkit/summit-sales-enablement-kit.md
  • docs/standards/CAC_v1.0.md
  • docs/standards/cognitive-security-protocol-v0.1.md
  • docs/standards/summit-attestation-bundle-v0.1.md
  • docs/standards/summit-category-language-and-glossary.md
  • docs/standards/summit-evidence-protocol.md
  • governance/branch-protection.required.json
  • governance/ga/required-checks.yaml
  • k8s/argo/admissibility-presync-check.yaml
  • k8s/base/kustomization.yaml
  • k8s/policies/kyverno-admissibility-enforcement.yaml
  • k8s/policies/kyverno-enforce-admissible-images.yaml
  • k8s/server-deployment.yaml
  • lib/admissibility.ts
  • package.json
  • policies/ops/containment-slo.yaml
  • policies/ops/failure-domain-map.yaml
  • policies/ops/failure-policy.yaml
  • policies/ops/rollout-policy.yaml
  • policies/ops/verified-properties.yaml
  • policies/security/security_gates.yml
  • policy/actions-allowlist.json
  • policy/admissibility/prohibited-dependencies.json
  • prompts/governance/governance-gates-and-cognitive-security-convergence@v1.md
  • prompts/governance/governance-gates-and-cognitive-security-convergence@v1.sha256
  • prompts/registry.yaml
  • schemas/det.schema.json
  • schemas/dvp.schema.json
  • schemas/governance/attestation-subject.schema.json
  • schemas/governance/blast-radius.schema.json
  • schemas/governance/containment-report.schema.json
  • schemas/governance/decision-proof.schema.json
  • schemas/governance/failure-domain.schema.json
  • schemas/governance/failure-policy.schema.json
  • schemas/governance/verification-summary.schema.json
  • scripts/check_branch_protection_convergence.mjs
  • scripts/ci/__tests__/governance_mutation_guard.test.mjs
  • scripts/ci/__tests__/verify_security_gate.test.mjs
  • scripts/ci/build_admissibility_evidence.mjs
  • scripts/ci/check_failure_domains.mjs
  • scripts/ci/check_failure_isolation.mjs
  • scripts/ci/generate-admissibility-bundle.ts
  • scripts/ci/verify-admissibility.ts
  • scripts/ci/verify-sbom-signature.sh
  • scripts/ci/verify_branch_protection.mjs
  • scripts/ci/verify_failure_semantics.mjs
  • scripts/ci/verify_required_checks_contract.mjs
  • scripts/ci/verify_security_gate.mjs
  • scripts/ci/verify_summit_attestation_bundle.mjs
  • scripts/configure-branch-protection.sh
  • scripts/pr-orchestrator-config.js
  • scripts/pr-orchestrator/README.md
  • scripts/queue-performance-monitor.js
  • tests/ci/admissibility.test.mts

Comment on lines +60 to +67
current_has_pr=false
current_has_paths=false
if grep -Eq '^[[:space:]]*(pull_request|pull_request_target):' "$f"; then
current_has_pr=true
fi
if grep -Eq '^[[:space:]]+paths:' "$f"; then
current_has_paths=true
fi
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

sample=$'on:\n  pull_request:\n  push:\n    paths:\n      - ".github/workflows/**"\n'

if printf '%s' "$sample" | grep -Eq '^[[:space:]]*(pull_request|pull_request_target):'; then
  echo "current_has_pr=true"
fi

if printf '%s' "$sample" | grep -Eq '^[[:space:]]+paths:'; then
  echo "current_has_paths=true"
fi

echo 'Expected policy result: PR trigger is present, but PR path scoping is absent.'

Repository: BrianCLong/summit

Length of output: 181


🏁 Script executed:

# Explore the repository structure and locate the file
find . -name "_policy-enforcer.yml" -type f 2>/dev/null | head -5

Repository: BrianCLong/summit

Length of output: 101


🏁 Script executed:

# Read the policy enforcer file to understand the full context
if [ -f ".github/workflows/_policy-enforcer.yml" ]; then
  cat -n ".github/workflows/_policy-enforcer.yml"
else
  echo "File not found at expected location"
  find . -name "*policy-enforcer*" 2>/dev/null
fi

Repository: BrianCLong/summit

Length of output: 4347


Parse on.pull_request{,_target}.paths specifically instead of grepping for any paths: key.

The current_has_paths and base_has_paths booleans go true for any indented paths: key anywhere in the workflow, including push.paths. A workflow with pull_request: trigger but lacking path restrictions will incorrectly pass this guard if that workflow also has push.paths or paths under any other trigger.

Example: A workflow with on: { pull_request:, push: { paths: [".github/workflows/**"] } } would incorrectly satisfy the policy, allowing a PR-facing trigger without actual PR path scoping.

This issue applies to both line ranges: 60-67 (current workflow check) and 80-87 (base workflow check).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/_policy-enforcer.yml around lines 60 - 67, The current
checks set current_has_paths/base_has_paths true for any indented "paths:"
anywhere; change them to only detect "paths:" that belong to the pull_request or
pull_request_target trigger. Replace the simple grep '^[[:space:]]+paths:' "$f"
logic with a targeted parse: first locate a pull_request or pull_request_target
key (grep -n for '^[[:space:]]*(pull_request|pull_request_target):'), then
inspect only the following indented block up until the next top-level key for a
'^[[:space:]]+paths:' line (or use yq to read .on.pull_request.paths
/.on.pull_request_target.paths). Apply the same replacement for both the
current_* (lines shown) and base_* checks so only pull-request-specific path
restrictions are considered.

Comment on lines +15 to +17
uses: sigstore/cosign-installer@v3.8.1
with:
cosign-release: 'v3.0.5'
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the cosign-installer action's supported version range and defaults
curl -s "https://api.github.com/repos/sigstore/cosign-installer/releases/tags/v3.8.1" | jq -r '.body' | head -50

Repository: BrianCLong/summit

Length of output: 65


🌐 Web query:

sigstore cosign-installer v3.8.1 cosign-release version compatibility

💡 Result:

With sigstore/cosign-installer@v3.8.1:

  • Default Cosign installed (if you don’t set cosign-release): v2.4.3. (raw.githubusercontent.com)
  • Valid cosign-release values:
  • Cosign v3+ compatibility: cosign-installer v3.x (including v3.8.1) is not suitable for installing Cosign v3+. Sigstore notes you must upgrade to cosign-installer v4 to install Cosign v3+. (github.com)

Citations:


🌐 Web query:

cosign v3.0.5 release

💡 Result:

Cosign v3.0.5 (sigstore/cosign) was released on February 19, 2026. Key points from the release notes: deprecations (rekor-entry-type flag, cosign triangulate, cosign copy), features (e.g., requiring signed timestamps with Rekor v2 entries; --local-image support with --new-bundle-format for v2/v3 signatures; mTLS support for TSA connections via signing config), and multiple panic-avoidance / verification bug fixes (including verifying the validity of the full certificate chain, not just the leaf). [1]

Security-wise, v3.0.5 patches GitHub advisory GHSA-wfqv-66vq-46rm / CVE-2026-24122 (“Signatures considered valid with certificates that outlive expired CA certificates”), affecting <= 3.0.4 and patched in 3.0.5; it’s rated Low and mainly impacts private deployments with customized PKIs, not the public Sigstore infrastructure. [2]

Sources: [1] [2]


🏁 Script executed:

#!/bin/bash
# Check if cosign v3.0.5 exists as a release
curl -s "https://api.github.com/repos/sigstore/cosign/releases" | jq -r '.[] | select(.tag_name == "v3.0.5") | .tag_name' | head -5

Repository: BrianCLong/summit

Length of output: 129


🏁 Script executed:

#!/bin/bash
# Check available versions from cosign releases (get latest few)
curl -s "https://api.github.com/repos/sigstore/cosign/releases?per_page=20" | jq -r '.[] | .tag_name' | head -20

Repository: BrianCLong/summit

Length of output: 129


Upgrade cosign-installer to v4.x for Cosign v3.0.5 compatibility.

sigstore/cosign-installer@v3.8.1 is incompatible with Cosign v3.x releases. The action requires cosign-installer@v4 or later to install Cosign v3.0.5. Update the action reference to resolve the incompatibility.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/cosign-verify.yml around lines 15 - 17, The workflow is
using sigstore/cosign-installer@v3.8.1 which is incompatible with cosign-release
'v3.0.5'; update the action reference to a v4.x release (for example change
uses: sigstore/cosign-installer@v3.8.1 to uses: sigstore/cosign-installer@v4 or
a specific v4 tag) so the cosign-release: 'v3.0.5' can be installed correctly.

Comment on lines +14 to +18
match:
any:
- resources:
kinds:
- Pod
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify potential blast radius: workloads missing admissibility label in repo manifests.
rg -n --iglob 'k8s/**/*.yaml' 'security\.summit\.io/admissibility'
rg -n --iglob 'k8s/**/*.yaml' 'kind:\s*(Deployment|StatefulSet|DaemonSet|Job|CronJob)' -C2

Repository: BrianCLong/summit

Length of output: 24399


🏁 Script executed:

cat -n k8s/policies/kyverno-admissibility-enforcement.yaml | head -60

Repository: BrianCLong/summit

Length of output: 2071


🏁 Script executed:

cat -n k8s/policies/kyverno-admissibility-enforcement.yaml

Repository: BrianCLong/summit

Length of output: 2071


Add namespace exclusions before enforcing this policy cluster-wide.

This ClusterPolicy targets all Pods across the cluster with validationFailureAction: Enforce and background: true, but only one workload in the repository (k8s/server-deployment.yaml) carries the required security.summit.io/admissibility: PASS label. Enforcing as-is will immediately block system workloads and third-party services in namespaces like kube-system, kyverno, argocd, and cert-manager.

All three rules (lines 13–24, 26–42, 44–49) match Pod resources without exclusions. Add namespace exclusions to prevent blocking critical cluster infrastructure:

Proposed exclusion pattern
     - name: require-admissibility-pass-label
       match:
         any:
           - resources:
               kinds:
                 - Pod
+      exclude:
+        any:
+          - resources:
+              namespaces:
+                - kube-system
+                - kyverno
+                - argocd
+                - cert-manager

Apply the same exclusion to all three rules.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
match:
any:
- resources:
kinds:
- Pod
match:
any:
- resources:
kinds:
- Pod
exclude:
any:
- resources:
namespaces:
- kube-system
- kyverno
- argocd
- cert-manager
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@k8s/policies/kyverno-admissibility-enforcement.yaml` around lines 14 - 18,
The ClusterPolicy rules currently match all Pod resources
(match.any.resources.kinds: Pod) with validationFailureAction: Enforce and
background: true; add namespace exclusions to each of the three rules that match
Pods by adding an exclude block under each rule's match (e.g., match: { any: [ {
resources: { kinds: [Pod], exclude: { namespaces:
["kube-system","kube-public","kube-node-lease","kyverno","argocd","cert-manager"]
} } } ] } ) so critical system and third-party namespaces are omitted while
keeping validationFailureAction and background as-is.

Comment on lines +21 to +24
- image: ghcr.io/*/summit-*
keyless:
issuer: https://token.actions.githubusercontent.com
subject: https://github.com/*/*/.github/workflows/deploy.yml@refs/heads/main
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Restrict image and signer scope to trusted repos.

Line 21 and Line 24 currently allow any GHCR org and any GitHub repo workflow subject, which weakens admission trust guarantees.

🔒 Proposed hardening
-        - image: ghcr.io/*/summit-*
+        - image: ghcr.io/<trusted-org>/summit-*
           keyless:
             issuer: https://token.actions.githubusercontent.com
-            subject: https://github.com/*/*/.github/workflows/deploy.yml@refs/heads/main
+            subject: https://github.com/<trusted-org>/<trusted-repo>/.github/workflows/deploy.yml@refs/heads/main
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- image: ghcr.io/*/summit-*
keyless:
issuer: https://token.actions.githubusercontent.com
subject: https://github.com/*/*/.github/workflows/deploy.yml@refs/heads/main
- image: ghcr.io/<trusted-org>/summit-*
keyless:
issuer: https://token.actions.githubusercontent.com
subject: https://github.com/<trusted-org>/<trusted-repo>/.github/workflows/deploy.yml@refs/heads/main
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@k8s/policies/kyverno-enforce-admissible-images.yaml` around lines 21 - 24,
The image and keyless subject patterns are too broad; tighten them by replacing
the wildcard GHCR org and generic workflow subject with explicit trusted
repositories and workflow paths: update the image value (currently
"ghcr.io/*/summit-*") to specific org(s)/repo(s) such as
"ghcr.io/trusted-org/summit-*" or an explicit list of allowed images, and change
the keyless.subject (currently
"https://github.com/*/*/.github/workflows/deploy.yml@refs/heads/main") to the
exact repository/workflow OIDC subject(s) like
"https://github.com/trusted-org/trusted-repo/.github/workflows/deploy.yml@refs/heads/main"
(or add multiple exact subjects) so the Kyverno policy only admits images signed
by known repos/workflows.

Comment on lines +35 to +47
- name: require-admissibility-labels
match:
any:
- resources:
kinds:
- Pod
validate:
message: Pods must carry a PASS admissibility label and a non-empty evidence digest.
pattern:
metadata:
labels:
summit.dev/admissibility: PASS
summit.dev/admissibility-digest: "?*"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Scope the label-enforcement rule or it will block non-Summit Pods.

Line 35–47 applies to every Pod in the cluster and requires Summit labels globally. Limit match scope (for example, to labeled namespaces) before enforcing.

🎯 Proposed scoping fix
     - name: require-admissibility-labels
       match:
         any:
           - resources:
               kinds:
                 - Pod
+              namespaceSelector:
+                matchLabels:
+                  summit.dev/enforce-admissibility: "true"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@k8s/policies/kyverno-enforce-admissible-images.yaml` around lines 35 - 47,
The rule require-admissibility-labels is matching every Pod cluster-wide;
restrict its scope by adding a namespaceSelector (or resources.namespaces) so
only Summit-managed namespaces are checked. Update the match block in
require-admissibility-labels to include a namespaceSelector with a
distinguishing label (e.g., matchLabels: {"summit.dev/managed":"true"}) or
target only pods in specific namespaces, keeping the validate pattern
(summit.dev/admissibility and summit.dev/admissibility-digest) unchanged so
non-Summit Pods are not blocked.

Comment on lines +15 to +30
function readYaml(filePath) {
const result = spawnSync(
'ruby',
[
'-e',
'require "yaml"; require "json"; puts JSON.generate(YAML.load_file(ARGV[0]))',
filePath
],
{ encoding: 'utf8' }
);

if (result.status !== 0) {
throw new Error(result.stderr || `Failed to parse YAML file: ${filePath}`);
}

return JSON.parse(result.stdout);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

git ls-files | grep -E "(check_failure_domains|\.yml?|yaml)" | head -20

Repository: BrianCLong/summit

Length of output: 691


🏁 Script executed:

cat -n scripts/ci/check_failure_domains.mjs 2>/dev/null | head -50

Repository: BrianCLong/summit

Length of output: 1631


🏁 Script executed:

# Check if Ruby is being used and how YAML parsing is handled
rg "YAML|Psych" --type js --type mjs -A 2 -B 2

Repository: BrianCLong/summit

Length of output: 88


🏁 Script executed:

# Check CI configuration to see if this script is run on PR input
fd -e yml -e yaml -e json | xargs grep -l "check_failure_domains" 2>/dev/null

Repository: BrianCLong/summit

Length of output: 100


🏁 Script executed:

# Look for any CI configuration files
git ls-files | grep -E "(github|gitlab|circleci|jenkins|\.ci)" | head -20

Repository: BrianCLong/summit

Length of output: 570


🏁 Script executed:

# Look for GitHub workflows that might call this script
fd -e yml -e yaml .github/workflows | xargs grep -l "check_failure_domains" 2>/dev/null || echo "Not found in workflows"

Repository: BrianCLong/summit

Length of output: 474


🏁 Script executed:

# Check for any references to check_failure_domains in the repo
rg "check_failure_domains" --type yaml --type json --type sh --type mjs

Repository: BrianCLong/summit

Length of output: 88


🏁 Script executed:

# Examine the full script to understand context, especially schema validation
cat -n scripts/ci/check_failure_domains.mjs | tail -100

Repository: BrianCLong/summit

Length of output: 3672


🏁 Script executed:

# Check if policies/ops/failure-domain-map.yaml is a tracked repository file
git ls-files | grep -E "failure-domain|failure_domain"

Repository: BrianCLong/summit

Length of output: 295


🏁 Script executed:

cat -n .github/workflows/failure-domain-declaration.yml

Repository: BrianCLong/summit

Length of output: 2170


🏁 Script executed:

# Check if policies/ops/failure-domain-map.yaml is modifiable in PRs (tracked in git)
git log --oneline policies/ops/failure-domain-map.yaml | head -5

Repository: BrianCLong/summit

Length of output: 106


🏁 Script executed:

# Check access control - is this file in a protected directory or if there are branch protections
cat .ci/branch-protection.json 2>/dev/null | head -50

Repository: BrianCLong/summit

Length of output: 158


Replace YAML.load_file with Psych.safe_load_file to prevent code execution via YAML deserialization.

This script executes on PR-controlled input (policies/ops/failure-domain-map.yaml). The YAML.load_file method deserializes arbitrary Ruby objects and can execute code. Switch to Psych.safe_load_file with restricted deserialization options:

Fix for Ruby YAML parsing
 function readYaml(filePath) {
   const result = spawnSync(
     'ruby',
     [
       '-e',
-      'require "yaml"; require "json"; puts JSON.generate(YAML.load_file(ARGV[0]))',
+      'require "yaml"; require "json"; require "psych"; puts JSON.generate(Psych.safe_load_file(ARGV[0], permitted_classes: [], permitted_symbols: [], aliases: false))',
       filePath
     ],
     { encoding: 'utf8' }
   );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function readYaml(filePath) {
const result = spawnSync(
'ruby',
[
'-e',
'require "yaml"; require "json"; puts JSON.generate(YAML.load_file(ARGV[0]))',
filePath
],
{ encoding: 'utf8' }
);
if (result.status !== 0) {
throw new Error(result.stderr || `Failed to parse YAML file: ${filePath}`);
}
return JSON.parse(result.stdout);
function readYaml(filePath) {
const result = spawnSync(
'ruby',
[
'-e',
'require "yaml"; require "json"; require "psych"; puts JSON.generate(Psych.safe_load_file(ARGV[0], permitted_classes: [], permitted_symbols: [], aliases: false))',
filePath
],
{ encoding: 'utf8' }
);
if (result.status !== 0) {
throw new Error(result.stderr || `Failed to parse YAML file: ${filePath}`);
}
return JSON.parse(result.stdout);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/ci/check_failure_domains.mjs` around lines 15 - 30, The readYaml
function currently invokes Ruby with YAML.load_file which can deserialize
arbitrary objects and execute code; change the inline Ruby snippet to require
'psych' and use Psych.safe_load_file(ARGV[0], permitted_classes: [],
permitted_symbols: [], aliases: false) instead of YAML.load_file so only basic
YAML types are allowed, and keep the JSON.generate wrapper as before; update
references to YAML.load_file in the spawn args to Psych.safe_load_file and
ensure the require line includes 'psych' to load the safe parser.

Comment on lines +126 to +137
if (!DECISION_VERDICTS.has(decisionProof?.verdict)) {
failedProperties.push('decision.verdict_valid');
}

const failedVerificationResults = Array.isArray(verificationSummary?.results)
? verificationSummary.results
.filter((result) => result?.status === 'FAIL')
.map((result) => result.property)
: [];

const status =
failedProperties.length === 0 && failedVerificationResults.length === 0 ? 'PASS' : 'FAIL';
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Non-admissible decision proofs currently pass this verifier.

If decision-proof.json says NOT_ADMISSIBLE or REVIEW_REQUIRED but the bundle is otherwise well-formed, status still becomes PASS. That lets a required check go green on an explicitly rejected bundle.

🔧 Fail closed on the final verdict
   if (!DECISION_VERDICTS.has(decisionProof?.verdict)) {
     failedProperties.push('decision.verdict_valid');
   }
+  if (decisionProof?.verdict !== 'ADMISSIBLE') {
+    failedProperties.push('decision.verdict_admissible');
+  }
 
   const failedVerificationResults = Array.isArray(verificationSummary?.results)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/ci/verify_summit_attestation_bundle.mjs` around lines 126 - 137, The
verifier currently treats non-admissible decision proofs as passing because
DECISION_VERDICTS.has(decisionProof?.verdict) allows values that are not
explicitly "ADMISSIBLE"; update the verdict check in the block that sets
failedProperties so that any verdict other than an explicit admissible value
(e.g., decisionProof?.verdict !== 'ADMISSIBLE' or not in the
allowedAdmissibleSet) pushes 'decision.verdict_valid' onto failedProperties —
alternatively explicitly treat 'NOT_ADMISSIBLE' and 'REVIEW_REQUIRED' as
failures by checking decisionProof.verdict and adding the same failedProperties
entry; keep the rest of the status computation (failedProperties +
failedVerificationResults) unchanged.

@BrianCLong
Copy link
Copy Markdown
Owner Author

Superseded by #22309. Governance-gate convergence is being carried forward only on the clean golden-path branch.

@BrianCLong BrianCLong closed this Mar 31, 2026
BrianCLong added a commit that referenced this pull request Mar 31, 2026
## Summary

Rebuilds the golden-main merge train from a clean `main` base and
converges the currently mergeable PR set into one replacement branch.

This branch absorbs:
- #22296
- #22279
- #22281
- #22282
- #22283
- #22284
- #22285
- #22295
- #22297
- #22286
- #22291
- #22280
- #22277
- unique non-conflicting surfaces from #22241
- the admissibility/CACert/failure-demo runtime lane from #22314

This branch supersedes:
- #22298 as the contaminated/conflicting convergence branch
- #22277 as a standalone merge vehicle
- #22241 as the broad mixed-purpose convergence vehicle once remaining
review is complete
- #22314 as the standalone admissibility lane now folded into the golden
path

This branch intentionally excludes:
- #22292 because it targets `merge-surge/staging`, not `main`

## Conflict policy used while absorbing #22241

When merging `#22241` on top of the cleaned train, the following files
conflicted and were resolved in favor of the current train versions so
the newer focused CI/governance repairs remain authoritative:
- `.github/ci/required-checks.json`
- `.github/workflows/drift-sentinel.yml`
- `.github/workflows/pr-gate.yml`
- `docs/ci/REQUIRED_CHECKS_POLICY.yml`
- `pnpm-lock.yaml`
- `scripts/ci/check_branch_protection_drift.mjs`
- `scripts/ci/validate_workflows.mjs`

All other `#22241` changes merged on top of the train.

## Mapping Change Summary

This convergence branch updates workflow, schema, and governance
contracts that control merge eligibility, admissibility evidence, and
deterministic trust artifacts.

## Diff

- Added admissibility/evidence/CACert surfaces including
`packages/evidence/schemas/decision_trace.schema.json`
- Tightened golden-lane workflow policy and drift handling in
`.github/workflows/_policy-enforcer.yml`,
`.github/workflows/execution-graph-reconciliation.yml`,
`.github/workflows/post-ga-hardening-enforcement.yml`,
`.github/workflows/merge-surge.yml`,
`.github/workflows/control-plane-drift.yml`
- Realigned governance state in `governance/pilot-ci-policy.json` and
`governance/branch-protection.json`
- Repaired deterministic reconciliation verification in
`scripts/ci/verify_execution_graph_reconciliation.mjs` and
`scripts/ci/drift-sentinel.mjs`

## Justification

The repo needed one mergeable replacement lane that restores
deterministic governance checks, folds the admissibility implementation
into the golden path, and suppresses broken optional PR workflows that
were blocking convergence without being canonical required checks.

## Impact

- Canonical pilot checks remain `pr-gate / gate` and `drift-sentinel /
enforce`
- Merge-train branches no longer fail ordinary small-PR enforcement
gates by construction
- Optional broken workflows are narrowed to their owned surfaces so they
stop contaminating this convergence lane and the immediate post-merge
main push
- Execution-graph reconciliation now accepts the repo’s canonical
snake_case trust bundle fields

## Rollback Plan

Revert commit `ce32b96c0f` from
`merge-train/golden-main-20260331-final`, then rerun the prior
golden-lane checks and restore the previous PR body.

## Backfill Plan

After the lane is green, backfill the same workflow scoping and
governance-contract repairs into any surviving PRs that still touch
`.github/workflows/**` or governance surfaces, then close superseded PRs
against `#22309`.

## Validation Evidence

Local validation completed:
- `node scripts/ci/drift-sentinel.mjs`
- `ruby -e 'require "yaml"; ... YAML.load_file(...)'` over all edited
workflow files
- `jq . governance/pilot-ci-policy.json`
- `jq . governance/branch-protection.json`
- merge-marker scan over all edited files returned clean

## Notes

- Live GitHub PR checks on the open PR set are being converged through
this single branch instead of salvaging each broken lane independently.
- I did not run the full local verification matrix in this session; this
PR is intended to give the repo one clean convergence lane for CI and
human review.
- After this PR lands, the absorbed PRs should be closed as superseded.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: Bot <bot@summit.ai>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Gemini CLI <gemini-cli@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant