Add K01-T001 deliverables: PHM org chart (DIA) and delegation matrix … #409
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Governance Gates (Comprehensive) | ||
| on: | ||
| pull_request: | ||
| branches: ['main', 'develop'] | ||
| workflow_dispatch: | ||
| jobs: | ||
| governance-checks: | ||
| runs-on: ubuntu-latest | ||
| name: CI Governance Gates | ||
| permissions: | ||
| contents: read | ||
| issues: write | ||
| pull-requests: write | ||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
| - name: Set up Python | ||
| uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: '3.x' | ||
| # GATE-001: Nomenclature Validation (BLOCKING) | ||
| - name: GATE-001 - Nomenclature Validation | ||
| id: nomenclature | ||
| run: | | ||
| echo "🔍 Running nomenclature validation..." | ||
| python validate_nomenclature.py --check-all --strict --verbose | ||
| continue-on-error: false | ||
| # GATE-005: Identifier Grammar Check (BLOCKING - when script exists) | ||
| - name: GATE-005 - Identifier Grammar Check | ||
| id: identifier | ||
| run: | | ||
| echo "🔍 Checking identifier grammar..." | ||
| if [ -f "scripts/validate_identifiers.py" ]; then | ||
| python scripts/validate_identifiers.py --all | ||
| else | ||
| echo "⚠️ Script not yet implemented (planned)" | ||
| fi | ||
| continue-on-error: true | ||
| # GATE-002: Schema Registration Check (BLOCKING) | ||
| - name: GATE-002 - Schema Registration Check | ||
| id: schema_registration | ||
| run: | | ||
| echo "🔍 Checking schema registration..." | ||
| set +e # Don't exit on error, we need to capture the exit code | ||
| OUTPUT=$(python scripts/validate_schema_registry.py --check-all --verbose 2>&1) | ||
| EXIT_CODE=$? | ||
| set -e | ||
| # Print output | ||
| echo "$OUTPUT" | ||
| # Check if registry is missing and output to GITHUB_OUTPUT | ||
| if echo "$OUTPUT" | grep -q "REGISTRY_MISSING"; then | ||
| echo "registry_missing=true" >> $GITHUB_OUTPUT | ||
| else | ||
| echo "registry_missing=false" >> $GITHUB_OUTPUT | ||
| fi | ||
| # Exit with the original exit code | ||
| exit $EXIT_CODE | ||
| continue-on-error: false | ||
| # Create issue if ATA 91 schema registry is missing | ||
| - name: Create Issue for Missing Schema Registry | ||
| if: always() && steps.schema_registration.outputs.registry_missing == 'true' | ||
| uses: actions/github-script@v7 | ||
| with: | ||
| script: | | ||
| // Check if an issue already exists | ||
| const issues = await github.rest.issues.listForRepo({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| labels: 'schema-registry-missing', | ||
| state: 'open' | ||
| }); | ||
| if (issues.data.length > 0) { | ||
| console.log('Issue already exists for missing schema registry'); | ||
| return; | ||
| } | ||
| // Create new issue | ||
| await github.rest.issues.create({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| title: '📋 Create ATA 91 Schema Registry', | ||
| body: `## Missing Schema Registry Detected | ||
| The CI governance gate (GATE-002) detected that the **ATA 91 schema registry** is missing from this repository. | ||
| ### Required Action | ||
| Create a schema registry CSV file following the ATA 91 schema governance policy. | ||
| ### Expected Location | ||
| The registry should be placed in one of the following locations: | ||
| - \`**/schema-registry*.csv\` | ||
| - \`**/91_*_TAB_*_schema-registry_*.csv\` | ||
| - \`**/schema_registry*.csv\` | ||
| ### Required Fields | ||
| The CSV should include the following columns: | ||
| - \`schema_id\`: Unique identifier for the schema | ||
| - \`version\`: Schema version | ||
| - \`namespace\`: Schema namespace | ||
| - \`owner\`: Responsible owner/team | ||
| - \`status\`: Current status (active, deprecated, draft, superseded) | ||
| - \`file_path\`: Path to the schema file | ||
| - \`description\`: Brief description of the schema | ||
| - \`content_hash\`: SHA-256 hash of schema content (optional) | ||
| ### Reference | ||
| - **Task**: T2-AI from K06 ATA 00 Tasklist | ||
| - **Gate**: GATE-002 (Schema Registration Check) | ||
| - **Policy**: CM's schema governance policy | ||
| --- | ||
| *This issue was automatically created by the CI governance gate.*`, | ||
| labels: ['schema-registry-missing', 'governance', 'K06', 'ATA-91'] | ||
| }); | ||
| console.log('Created issue for missing schema registry'); | ||
| # GATE-003: Trace Link Integrity Check (WARNING during PORTAL build-out) | ||
| # TODO: Change to BLOCKING once PORTAL structure is complete (target: Q2 2026) | ||
| # Tracked in: PORTAL build-out plan (docs/GATE-003-TRACE-LINK-VALIDATION.md) | ||
| - name: GATE-003 - Trace Link Integrity Check | ||
| id: trace_integrity | ||
| run: | | ||
| echo "🔍 Validating trace link integrity..." | ||
| set +e | ||
| OUTPUT=$(python scripts/validate_trace_links.py --check-all --skip-templates 2>&1) | ||
| EXIT_CODE=$? | ||
| set -e | ||
| echo "$OUTPUT" | ||
| # Extract broken link count from validator output | ||
| # Note: This relies on the validator's output format. Consider adding JSON output mode in future. | ||
| BROKEN_COUNT=$(echo "$OUTPUT" | grep -oP '(?<=❌ VALIDATION FAILED - )\d+' || echo "0") | ||
| echo "broken_count=$BROKEN_COUNT" >> $GITHUB_OUTPUT | ||
| # Check for broken links | ||
| if echo "$OUTPUT" | grep -q "VALIDATION FAILED"; then | ||
| echo "trace_failed=true" >> $GITHUB_OUTPUT | ||
| echo "⚠️ Note: $BROKEN_COUNT broken links found (expected during PORTAL build-out)" | ||
| echo "⚠️ Links to planned content are acceptable. See docs/GATE-003-STATUS-REPORT.md" | ||
| # Temporarily exit 0 to make gate pass with warning during build-out phase | ||
| # This allows PRs to proceed while PORTAL structure is being built out | ||
| exit 0 | ||
| else | ||
| echo "trace_failed=false" >> $GITHUB_OUTPUT | ||
| exit 0 | ||
| fi | ||
| continue-on-error: false | ||
| # GATE-LINK-001: Internal Link Integrity Check (BLOCKING for PR^3-2/PR^3-3, WARN for PR^3-1) | ||
| - name: GATE-LINK-001 - Internal Link Integrity Check | ||
| id: link_integrity | ||
| run: | | ||
| echo "🔍 Validating internal links in Markdown files..." | ||
| # Determine PR^3 mode from branch or default to block | ||
| MODE="block" # PR^3-2/PR^3-3 mode | ||
| if [[ "${{ github.base_ref }}" == "develop" ]]; then | ||
| MODE="warn" # PR^3-1 mode | ||
| fi | ||
| set +e | ||
| OUTPUT=$(python scripts/validate_internal_links.py --scope repo --mode $MODE 2>&1) | ||
| EXIT_CODE=$? | ||
| set -e | ||
| echo "$OUTPUT" | ||
| # Check for broken links count | ||
| BROKEN_COUNT=$(echo "$OUTPUT" | grep "Broken internal links:" | awk '{print $NF}') | ||
| echo "broken_links=$BROKEN_COUNT" >> $GITHUB_OUTPUT | ||
| echo "link_mode=$MODE" >> $GITHUB_OUTPUT | ||
| exit $EXIT_CODE | ||
| continue-on-error: false | ||
| # GATE-004: Namespace Deduplication Check (BLOCKING) | ||
| - name: GATE-004 - Namespace Deduplication Check | ||
| id: namespace_dedup | ||
| run: | | ||
| echo "🔍 Checking for duplicate namespace IDs..." | ||
| python scripts/check_ata99_registry.py --deduplicate | ||
| continue-on-error: false | ||
| # GATE-006: Detect Governance Changes (LABELING) | ||
| - name: GATE-006 - Detect Governance Changes | ||
| id: governance_changes | ||
| if: github.event_name == 'pull_request' | ||
| run: | | ||
| echo "🔍 Detecting governance-impacting changes..." | ||
| CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...${{ github.sha }}) | ||
| echo "Changed files:" | ||
| echo "$CHANGED_FILES" | ||
| # Check for governance-impacting patterns | ||
| GOVERNANCE_CHANGE=false | ||
| # Pattern 1: Standards (STD files in ATA 00) | ||
| if echo "$CHANGED_FILES" | grep -E "00_00_STD_.*\.md$"; then | ||
| echo "✓ Governance standard change detected" | ||
| GOVERNANCE_CHANGE=true | ||
| fi | ||
| # Pattern 2: CI workflows | ||
| if echo "$CHANGED_FILES" | grep -E "\.github/workflows/.*\.yml$"; then | ||
| echo "✓ CI workflow change detected" | ||
| GOVERNANCE_CHANGE=true | ||
| fi | ||
| # Pattern 3: Validation scripts | ||
| if echo "$CHANGED_FILES" | grep -E "validate_.*\.py$|scripts/(check|validate|detect).*\.py$"; then | ||
| echo "✓ Validation script change detected" | ||
| GOVERNANCE_CHANGE=true | ||
| fi | ||
| # Output result | ||
| if [ "$GOVERNANCE_CHANGE" = true ]; then | ||
| echo "governance_change=true" >> $GITHUB_OUTPUT | ||
| echo "⚠️ Governance change detected - CM WG approval required" | ||
| exit 0 | ||
| else | ||
| echo "governance_change=false" >> $GITHUB_OUTPUT | ||
| echo "✅ No governance changes detected" | ||
| fi | ||
| # GATE-006: Label PR for Governance Review | ||
| - name: Label PR as Governance Review Required | ||
| if: github.event_name == 'pull_request' && steps.governance_changes.outputs.governance_change == 'true' | ||
| uses: actions/github-script@v7 | ||
| with: | ||
| script: | | ||
| // Add label | ||
| await github.rest.issues.addLabels({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: context.issue.number, | ||
| labels: ['governance-review-required'] | ||
| }); | ||
| // Add comment | ||
| await github.rest.issues.createComment({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: context.issue.number, | ||
| body: `## ⚠️ Governance Change Detected (GATE-006) | ||
| This PR modifies governance-impacting files and requires **CM WG approval** before merge. | ||
| ### Detected Changes | ||
| - Governance standards (STD files) | ||
| - CI/CD workflows | ||
| - Validation scripts | ||
| ### Required Actions | ||
| 1. **Request review** from a CM WG member | ||
| 2. **Address feedback** from CM WG review | ||
| 3. **Await approval** before merging | ||
| ### Reference | ||
| - **Policy**: 00_00_STD_LC01_SPACET_governance-reference-policy_I01-R01.md §6.3 | ||
| - **Gate**: GATE-006 (Governance Change Detection) | ||
| - **Index**: 00_00_IDX_LC01_SPACET_ci-governance-gates_I01-R01.md | ||
| ` | ||
| }); | ||
| # GATE-007: Breaking Schema Changes (BLOCKING - when script exists) | ||
| - name: GATE-007 - Breaking Schema Change Detection | ||
| id: schema_breaking | ||
| run: | | ||
| echo "🔍 Detecting breaking schema changes..." | ||
| if [ -f "scripts/detect_schema_breaking_changes.py" ]; then | ||
| python scripts/detect_schema_breaking_changes.py --registry ATA91 | ||
| else | ||
| echo "⚠️ Script not yet implemented (planned)" | ||
| fi | ||
| continue-on-error: true | ||
| # GATE-008: Evidence Link Validation (WARNING) | ||
| - name: GATE-008 - Evidence Link Validation | ||
| id: evidence_links | ||
| run: | | ||
| echo "🔍 Validating evidence links..." | ||
| if [ -f "scripts/validate_evidence_links.py" ]; then | ||
| python scripts/validate_evidence_links.py --all | ||
| else | ||
| echo "⚠️ Script not yet implemented (planned)" | ||
| fi | ||
| continue-on-error: true | ||
| # Summary Report | ||
| - name: Generate Gate Summary | ||
| if: always() | ||
| run: | | ||
| echo "## 📊 Governance Gates Summary" | ||
| echo "" | ||
| echo "| Gate | Status | Description |" | ||
| echo "|------|--------|-------------|" | ||
| echo "| GATE-001 | ${{ steps.nomenclature.outcome == 'success' && '✅ PASS' || '❌ FAIL' }} | Nomenclature Validation |" | ||
| echo "| GATE-005 | ⏭️ PLANNED | Identifier Grammar Check |" | ||
| echo "| GATE-002 | ${{ steps.schema_registration.outcome == 'success' && '✅ PASS' || '❌ FAIL' }} | Schema Registration Check |" | ||
| echo "| GATE-003 | ${{ steps.trace_integrity.outcome == 'success' && (steps.trace_integrity.outputs.broken_count > 0 && '⚠️ PASS (warnings)' || '✅ PASS') || '❌ FAIL' }} | Trace Link Integrity (${{ steps.trace_integrity.outputs.broken_count || 0 }} links to planned content) |" | ||
| echo "| GATE-LINK-001 | ${{ steps.link_integrity.outcome == 'success' && '✅ PASS' || '❌ FAIL' }} | Internal Link Integrity (mode: ${{ steps.link_integrity.outputs.link_mode }}) |" | ||
| echo "| GATE-004 | ${{ steps.namespace_dedup.outcome == 'success' && '✅ PASS' || '❌ FAIL' }} | Namespace Deduplication |" | ||
| echo "| GATE-006 | ${{ steps.governance_changes.outputs.governance_change == 'true' && '⚠️ REVIEW' || '✅ PASS' }} | Governance Change Detection |" | ||
| echo "| GATE-007 | ⏭️ PLANNED | Breaking Schema Detection |" | ||
| echo "| GATE-008 | ⏭️ PLANNED | Evidence Link Validation |" | ||
| echo "" | ||
| echo "✅ PASS: Gate passed" | ||
| echo "❌ FAIL: Gate failed (blocking)" | ||
| echo "⚠️ REVIEW: Manual review required" | ||
| echo "⚠️ WARNING: Issues detected (non-blocking)" | ||
| echo "⏭️ PLANNED: Gate not yet implemented" | ||